Browse Source

Migration of major changes from the 'unstable' branch

- Additions and corrections to scripts
- Changed project configuration method
- Modified project configuration description in README.md
- The main changes from the 'unstable' branch were selected and adapted using the cherry pick method
TonyKurts 1 year ago
parent
commit
536dd5564a
58 changed files with 2002 additions and 522 deletions
  1. 5 3
      .gitignore
  2. 34 22
      README.md
  3. 2 0
      SharixAdmin/admin.py
  4. 21 4
      SharixAdmin/forms.py
  5. BIN
      SharixAdmin/locale/ru/LC_MESSAGES/django.mo
  6. 412 0
      SharixAdmin/locale/ru/LC_MESSAGES/django.po
  7. BIN
      SharixAdmin/static/SharixAdmin/img/logo.png
  8. 0 6
      SharixAdmin/static/SharixAdmin/img/logo.svg
  9. 28 28
      SharixAdmin/tables.py
  10. 37 0
      SharixAdmin/templates/SharixAdmin/auth.html
  11. 57 0
      SharixAdmin/templates/SharixAdmin/balance.html
  12. 10 0
      SharixAdmin/templates/SharixAdmin/balance_success.html
  13. 18 0
      SharixAdmin/templates/SharixAdmin/base.html
  14. 163 0
      SharixAdmin/templates/SharixAdmin/index.html
  15. 38 0
      SharixAdmin/templates/SharixAdmin/main.html
  16. 22 0
      SharixAdmin/templates/SharixAdmin/partner_information_form.html
  17. 38 0
      SharixAdmin/templates/SharixAdmin/partners.html
  18. 38 0
      SharixAdmin/templates/SharixAdmin/provider.html
  19. 38 0
      SharixAdmin/templates/SharixAdmin/resource.html
  20. 10 0
      SharixAdmin/templates/SharixAdmin/schema.html
  21. 12 0
      SharixAdmin/templates/SharixAdmin/senderform.html
  22. 38 0
      SharixAdmin/templates/SharixAdmin/service.html
  23. 26 0
      SharixAdmin/templates/SharixAdmin/service_information_form.html
  24. 49 0
      SharixAdmin/templates/SharixAdmin/service_tariff.html
  25. 22 0
      SharixAdmin/templates/SharixAdmin/service_tariff_form.html
  26. 49 0
      SharixAdmin/templates/SharixAdmin/service_type.html
  27. 15 0
      SharixAdmin/templates/SharixAdmin/service_type_delete.html
  28. 22 0
      SharixAdmin/templates/SharixAdmin/service_type_form.html
  29. 10 0
      SharixAdmin/templates/SharixAdmin/test.html
  30. 26 0
      SharixAdmin/templates/SharixAdmin/trans_carried.html
  31. 16 0
      SharixAdmin/templates/SharixAdmin/transactions.html
  32. 3 2
      SharixAdmin/urls.py
  33. 6 5
      SharixAdmin/views/balance.py
  34. 20 19
      SharixAdmin/views/context.py
  35. 3 1
      SharixAdmin/views/index.py
  36. 120 5
      SharixAdmin/views/partner_info.py
  37. 3 1
      SharixAdmin/views/partners.py
  38. 2 1
      SharixAdmin/views/provider.py
  39. 2 1
      SharixAdmin/views/resource.py
  40. 2 1
      SharixAdmin/views/service.py
  41. 33 3
      SharixAdmin/views/service_info.py
  42. 4 3
      SharixAdmin/views/service_tariff.py
  43. 5 4
      SharixAdmin/views/service_type.py
  44. 2 1
      SharixAdmin/views/test.py
  45. 2 1
      SharixAdmin/views/trans_id.py
  46. 2 1
      SharixAdmin/views/transactions.py
  47. 2 1
      SharixAdmin/views/user_info.py
  48. 9 8
      bin/install.bat
  49. 10 9
      bin/install.sh
  50. 0 372
      core/_config.py
  51. 49 0
      core/_settings_vars.py
  52. 8 3
      core/gunicorn.py
  53. 400 5
      core/settings.py
  54. 12 4
      core/urls.py
  55. 0 8
      core/utils.py
  56. 46 0
      core/utils/AuthAPI.py
  57. BIN
      media/tasks/attachments/1/payment.png
  58. 1 0
      requirements.txt

+ 5 - 3
.gitignore

@@ -14,7 +14,9 @@ __pycache__/
 tickets/
 metaservicesynced/
 conf/
-SharixAdmin/templates/SharixAdmin/
+design_template/
+webservice_running/
+landing/
 
 # Django
 migrations/
@@ -35,5 +37,5 @@ __pycache__/
 *.*.swp
 .DS_Store
 
-# Project configuration
-core/config.py
+# Project configuration variables
+core/settings_vars.py

+ 34 - 22
README.md

@@ -13,39 +13,51 @@ For the initial configuration, run:
 
 ## Configuration
 
-After executing the installation script, the file *core/_config.py* will be copied to the *core/config.py* (only if *core/config.py* does not exist yet). It contains default settings of all modules and applications used in Django project in the form of classes, where each attribute represents one setting. These classes are then used to apply all the necessary settings inside their own configuration files using the setup() function. 
+For basic project configuration when deploying, use the *core/settings_vars.py*. This file is automatically created during the installation script execution, in case this file has not been created yet. It is a copy of *core/_settings_vars.py* and contains some default settings that allow the project to run locally and is more suitable for development.
 
-For example, this is how all the customizations for Gunicorn are defined in the *core/config.py* file:
+Be careful when adding new settings during development and remember to add them to *core/_settings_vars.py*, as *core/settings_vars.py* is ignored by Git for security reasons.
 
-```python
-# core/config.py
-
-class ConfigGunicorn:
-    bind = "127.0.0.1"
-    workers = 2
-    worker_class = "sync"
-    threads = 4
-    timeout = 30
-    max_requests = 1000
-    capture_output = True
-```
+## Utilities
+
+Utilities provides important functionality to web-application, so it is important to know and understand how they work. They are stored in *core/utils*.
+
+### AuthAPI
 
-And this is how these settings are applied in the *core/gunicorn.py* configuration file used when starting Gunicorn:
+That class provides the ability to authenticate an application account through the
+API and store these authentication tokens.
+
+Modules using the API should log in ShariX system using this class.
+
+#### Setting up
 
 ```python
-# core/gunicorn.py
+# core/settings_vars.py
 
-from core.utils import setup
-from core.config import ConfigGunicorn
+API_URL = 'http://127.0.0.1:8000'
+```
 
-setup(locals(), ConfigGunicorn)
+```python
+# <module>/apps.py
+
+from core.utils.AuthAPI import AuthAPI
+auth_api = AuthAPI("<module_login>", "<module_password>")
 ```
 
-This approach provides more convenient project configuration and allows you to store settings for development and production use.
+#### Usage example
+
+```python
+# <module>/<file>.py
+
+import requests
+from <module>.apps import auth_api 
+from core.settings import API_URL
 
-To configure special settings, such as changing the database type or specifying domain names for deployment in production that do not match the default settings for the web application, make changes to the *core/config.py* file. If these changes later become necessary for the basic installation of the web application, they should also be made in *core/_config.py*.
+# You can use api.headers to get the corret authorization header in your requests.
+requests.get(f"{API_URL}/tickets/api/tickets/", headers=auth_api.headers)
 
-To apply your own classes with configurations, follow the usage example above.
+# Or you can get just token.
+print(auth_api.token)
+```
 
 ## Launch 
 

+ 2 - 0
SharixAdmin/admin.py

@@ -53,6 +53,8 @@ class SharixUserAdmin(adm.UserAdmin):
     list_display = (
         'username',
         'phone_number',
+        'first_name',
+        'last_name'
     )
     list_filter = (
         'last_login',

+ 21 - 4
SharixAdmin/forms.py

@@ -123,8 +123,13 @@ class ServiceInformationCreateForm(forms.ModelForm):
 
     class Meta:
         model = Service
-        fields = ["servicetype_id", "id_provider"]
-        exclude = ["resource_id"]
+        fields = "__all__"
+        exclude = ["id", 
+                   "is_global", 
+                   "is_visible", 
+                   "ticket_status",
+                   "id_metaservice",
+                   "resource_id"]
 
         widgets = {
             #'servicetype_id': forms.CharField(max_length=255)
@@ -145,7 +150,13 @@ class PartnerInformationUpdateForm(forms.ModelForm):
 
     class Meta:
         model = Company
-        fields = ['legal_name', 'address', 'repr_id' ]
+        fields = "__all__"
+        exclude = ["id", "ticket_status",
+                   "is_global", 
+                   "is_visible", 
+                   "id_metaservice",
+                   "status"
+                   ]
         widgets = {
             'description': forms.Select(attrs={'class': 'form-select'}),
             'repr_id': forms.Select(attrs={'class': 'form-select'}),
@@ -161,7 +172,13 @@ class PartnerInformationCreateForm(forms.ModelForm):
     # legal_name = forms.Fi()
     class Meta:
         model = Company
-        fields = ['legal_name', 'address', 'repr_id']
+        fields = "__all__"
+        exclude = ["id", "ticket_status",
+                   "is_global", 
+                   "is_visible", 
+                   "id_metaservice",
+                   "status"
+                   ]
 
         widgets = {
             'description': forms.Select(attrs={'class': 'form-select'}),

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


+ 412 - 0
SharixAdmin/locale/ru/LC_MESSAGES/django.po

@@ -0,0 +1,412 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2023-06-01 22:28+0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
+"%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n"
+"%100>=11 && n%100<=14)? 2 : 3);\n"
+
+#: .\tables.py:11
+msgid "Owner"
+msgstr "Владелец"
+
+#: .\tables.py:12 .\views\trans_id.py:9
+msgid "Service"
+msgstr "Услуга"
+
+#: .\tables.py:13
+msgid "Points"
+msgstr "Баллы"
+
+#: .\tables.py:14
+msgid "Registration date"
+msgstr "Дата оформления"
+
+#: .\tables.py:15 .\tables.py:34 .\tables.py:56 .\tables.py:76
+msgid "Status"
+msgstr "Статус"
+
+#: .\tables.py:15
+msgid "Successful, not successful"
+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 "ИД"
+
+#: .\tables.py:31
+msgid "Legal entity"
+msgstr "Юрлицо"
+
+#: .\tables.py:32 .\tables.py:55
+msgid "Responsible"
+msgstr "Ответственный"
+
+#: .\tables.py:74
+msgid "Full Name"
+msgstr "ФИО"
+
+#: .\tables.py:95
+msgid "Name of the tariff"
+msgstr "Название тарифа"
+
+#: .\tables.py:97
+msgid "Name of the service scheme"
+msgstr "Название схемы услуги"
+
+#: .\tables.py:98
+msgid "Activity"
+msgstr "Активность"
+
+#: .\tables.py:140
+msgid "Description of the service"
+msgstr "Описание услуги (сервиса)"
+
+#: .\tables.py:147
+msgid "Cost km."
+msgstr "Стоимость км."
+
+#: .\tables.py:148
+msgid "Cost min."
+msgstr "Стоимость мин."
+
+#: .\tables.py:149
+msgid "Cost of service"
+msgstr "Стоимость услуги"
+
+#: .\templates\SharixAdmin\auth.html:10
+msgid "Log in"
+msgstr "Авторизуйтесь"
+
+#: .\templates\SharixAdmin\auth.html:26
+msgid "Please, enter the correct phone number and password."
+msgstr "Пожалуйста, введите правильный номер телефона и пароль."
+
+#: .\templates\SharixAdmin\auth.html:29
+msgid "Login"
+msgstr "Войти"
+
+#: .\templates\SharixAdmin\balance.html:11
+msgid ""
+"Payment by card and bank details is available. When paying for an order with "
+"a bank card, <br> payment processing takes place on the page of the PAYMO "
+"payment provider."
+msgstr ""
+"Доступна оплата картой и банковскими реквизитами. При оплате заказа с "
+"помощью банковская карта, <br> обработка платежа происходит на странице "
+"PAYMO поставщик платежей."
+
+#: .\templates\SharixAdmin\balance.html:14
+msgid ""
+"You will need to enter your bank card details: MIR; VISA International; <br> "
+"Mastercard Worldwide."
+msgstr ""
+"Вам нужно будет ввести данные вашей банковской карты: MIR; VISA "
+"International; <br> Mastercard Worldwide."
+
+#: .\templates\SharixAdmin\balance.html:17
+msgid "3D-Secure maps only."
+msgstr "Только защищенные 3D-карты."
+
+#: .\templates\SharixAdmin\balance.html:21
+#: .\templates\SharixAdmin\balance.html:22
+msgid "Enter the required amount"
+msgstr "Введите требуемую сумму"
+
+#: .\templates\SharixAdmin\balance.html:25
+msgid ""
+"After replenishment, the funds can be used to pay for the services of "
+"subsidiary services."
+msgstr ""
+"После пополнения средства могут быть использованы для оплаты услуг "
+"вспомогательных служб."
+
+#: .\templates\SharixAdmin\balance.html:34
+msgid "Replenish"
+msgstr "Пополнить"
+
+#: .\templates\SharixAdmin\balance.html:36
+msgid "Back"
+msgstr "Назад"
+
+#: .\templates\SharixAdmin\balance.html:40
+msgid "Requisites"
+msgstr "Реквизиты"
+
+#: .\templates\SharixAdmin\balance.html:42
+msgid ""
+"<p>Legal address:<b>199155, the city of St. Petersburg, Zheleznovodskaya "
+"street, house 32 letter d, room 22-n office 1-8</b></p> <p>Email: "
+"<b>info@sharix-app.org </b></p> <p>TIN: <b>7801685119</b></p> <p>Bank: "
+"<b>Moscow branch of AKB MKPB (JSC)</b></p> <p>Bic: <b>044525610</b></p> "
+"<p>Current account: <b>40702810800400000025</b></p> <p>Correspondent "
+"account: <b>30101810645250000610</b></p>"
+msgstr ""
+"<p>Юридический адрес:<b>199155, город Санкт-Петербург, Железноводская улица, "
+"дом 32, литера d, комната 22-n, офис 1-8</b></p> <p>Электронная почта: "
+"<b>info@sharix-app.org </b></p> <p>НОМЕР: <b>7801685119</b></p> <p>Банк: "
+"<b>Московский филиал АКБ МКПБ (АО)</b></p> <p>Бик: <b>044525610</b></p> "
+"<p>Текущий счет: <b>40702810800400000025</b></p> <p>Корреспондент учетная "
+"запись: <b>30101810645250000610</b></p>"
+
+#: .\templates\SharixAdmin\index.html:17
+msgid "ShariX Menu"
+msgstr "Sharix Меню"
+
+#: .\templates\SharixAdmin\index.html:32
+msgid "Change"
+msgstr ""
+
+#: .\templates\SharixAdmin\index.html:84
+msgid "Contacts"
+msgstr "Контакты"
+
+#: .\templates\SharixAdmin\index.html:85
+msgid "Terms of use"
+msgstr "Условия использования"
+
+#: .\templates\SharixAdmin\index.html:86 .\templates\SharixAdmin\main.html:12
+msgid "Privacy policy"
+msgstr "Политика конфиденциальности"
+
+#: .\templates\SharixAdmin\index.html:88
+msgid "Log out"
+msgstr "Выйти"
+
+#: .\templates\SharixAdmin\main.html:11
+msgid "Documentation"
+msgstr "Документация"
+
+#: .\templates\SharixAdmin\main.html:13
+msgid "Rules for the provision of services"
+msgstr "Правила предоставления услуг"
+
+#: .\templates\SharixAdmin\main.html:14
+msgid "Procedure for the provision of services"
+msgstr "Порядок предоставления услуг"
+
+#: .\templates\SharixAdmin\main.html:15
+msgid "List of services"
+msgstr "Перечень предоставляемых услуг"
+
+#: .\templates\SharixAdmin\main.html:16
+msgid "Scheme 1"
+msgstr "Схема 1"
+
+#: .\templates\SharixAdmin\main.html:16
+msgid "Scheme 2"
+msgstr "Схема 2"
+
+#: .\templates\SharixAdmin\main.html:16
+msgid "Scheme 3"
+msgstr "Схема 3"
+
+#: .\templates\SharixAdmin\main.html:16
+msgid "API Docs"
+msgstr "Документация по API"
+
+#: .\templates\SharixAdmin\main.html:21
+#, python-format
+msgid "<p>User: <b>%(user)s</b></p>"
+msgstr "<p>Пользователь: <b>%(user)s</b></p>"
+
+#: .\templates\SharixAdmin\main.html:24
+#, python-format
+msgid "<p>Phone number: <b>%(phone)s</b></p>"
+msgstr "<p>Номер телефона: <b>%(phone)s</b></p>"
+
+#: .\templates\SharixAdmin\main.html:27
+#, python-format
+msgid "<p>Date of registration: <b>%(date)s</b></p>"
+msgstr "<p>Дата регистрации: <b>%(date)s</b></p>"
+
+#: .\templates\SharixAdmin\main.html:30
+#, python-format
+msgid "<p>Balance: <b>%(balance)s points</b></p>"
+msgstr "<p>Баланс: <b>%(balance)s баллов</b></p>"
+
+#: .\templates\SharixAdmin\main.html:33
+msgid "Buy points"
+msgstr "Купить баллы"
+
+#: .\templates\SharixAdmin\partner_information_form.html:19
+#: .\templates\SharixAdmin\senderform.html:10
+#: .\templates\SharixAdmin\service_information_form.html:23
+#: .\templates\SharixAdmin\service_tariff_form.html:19
+#: .\templates\SharixAdmin\service_type_form.html:19
+msgid "Submit"
+msgstr "Отправить"
+
+#: .\templates\SharixAdmin\senderform.html:7
+msgid "The message will be sent to the following users:"
+msgstr "Сообщение будет отправлено следующим пользователям:"
+
+#: .\templates\SharixAdmin\senderform.html:9
+msgid "send_phone"
+msgstr "Отправить телефон"
+
+#: .\templates\SharixAdmin\service_tariff.html:48
+#: .\templates\SharixAdmin\service_type.html:48
+msgid "Add"
+msgstr "Добавить"
+
+#: .\templates\SharixAdmin\service_type_delete.html:9
+#, python-format
+msgid "Are you sure you want to delete \\\"%%(object.caption)s\\\"?"
+msgstr "Вы уверены, что хотите удалить \\\"%%(object.caption)s\\\"?"
+
+#: .\templates\SharixAdmin\service_type_delete.html:12
+msgid "Delete"
+msgstr "Удалить"
+
+#: .\templates\SharixAdmin\test.html:7
+msgid "These pages are under development"
+msgstr "Данные страницы находятся в разработке"
+
+#: .\templates\SharixAdmin\trans_carried.html:6
+#: .\templates\SharixAdmin\transactions.html:7
+msgid "User: "
+msgstr "Пользователь: "
+
+#: .\templates\SharixAdmin\trans_carried.html:7
+msgid "Balance: "
+msgstr "Баланс: "
+
+#: .\templates\SharixAdmin\trans_carried.html:15
+msgid "Price: "
+msgstr "Цена: "
+
+#: .\templates\SharixAdmin\trans_carried.html:16
+msgid "Owner: "
+msgstr "Владелец: "
+
+#: .\templates\SharixAdmin\trans_carried.html:17
+msgid "Date of service: "
+msgstr "Дата предоставления услуги: "
+
+#: .\templates\SharixAdmin\trans_carried.html:18
+msgid "Conducted: "
+msgstr "Проведен: "
+
+#: .\templates\SharixAdmin\trans_carried.html:23
+msgid "Spend"
+msgstr "Потратить"
+
+#: .\templates\SharixAdmin\transactions.html:8
+#, python-format
+msgid "Balance: %(wallet.balance)s points"
+msgstr "Баланс: %(wallet.balance)s баллов"
+
+#: .\templates\SharixAdmin\transactions.html:11
+#: .\templates\SharixAdmin\transactions.html:12
+msgid "Search"
+msgstr "Поиск"
+
+#: .\views\balance.py:9 .\views\balance.py:14 .\views\balance.py:20
+msgid "Top up your balance"
+msgstr "Пополните свой баланс"
+
+#: .\views\balance.py:15
+msgid "The payment was successful ;)"
+msgstr "the payment was successful ;)"
+
+#: .\views\balance.py:21
+msgid "Payment failed ;("
+msgstr "Платеж не прошел ;("
+
+#: .\views\context.py:5 .\views\index.py:14
+msgid "Home/Balance"
+msgstr "Главная/Баланс"
+
+#: .\views\context.py:6
+msgid "Payment information"
+msgstr "Платежная информация"
+
+#: .\views\context.py:7 .\views\transactions.py:10
+msgid "Payment history"
+msgstr "История платежей"
+
+#: .\views\context.py:8
+msgid "Courses"
+msgstr "Курсы"
+
+#: .\views\context.py:9
+msgid "Personal information"
+msgstr "Личная информация"
+
+#: .\views\context.py:10
+msgid "Service management"
+msgstr "Управление сервисами"
+
+#: .\views\context.py:11
+msgid "My connections"
+msgstr "Мои связи"
+
+#: .\views\context.py:12
+msgid "Partnership"
+msgstr "Сотрудничество"
+
+#: .\views\context.py:13
+msgid "Techsupport"
+msgstr "Техподдержка"
+
+#: .\views\context.py:14
+msgid "My tickets"
+msgstr "Мои заявки"
+
+#: .\views\context.py:15 .\views\provider.py:19 .\views\service_tariff.py:41
+msgid "Performers"
+msgstr "Исполнители"
+
+#: .\views\context.py:17 .\views\service_tariff.py:19
+#: .\views\service_tariff.py:61
+msgid "Service rates"
+msgstr "Тарифы услуг"
+
+#: .\views\context.py:19 .\views\partners.py:20
+msgid "Partners"
+msgstr "Партнеры"
+
+#: .\views\context.py:21 .\views\resource.py:19
+msgid "Resources"
+msgstr "Ресурсы"
+
+#: .\views\context.py:23 .\views\service_type.py:19
+msgid "Service services"
+msgstr "Услуги сервиса"
+
+#: .\views\context.py:25 .\views\service_info.py:17
+msgid "Information about the service"
+msgstr "Информация о сервисе"
+
+#: .\views\context.py:27 .\views\partner_info.py:19 .\views\partner_info.py:41
+#: .\views\partner_info.py:57
+msgid "Partner Information"
+msgstr "Информация о партнере"
+
+#: .\views\context.py:29 .\views\service.py:18
+msgid "Rates"
+msgstr "Тарифы"
+
+#: .\views\context.py:31 .\views\user_info.py:17
+msgid "User Management"
+msgstr "Управление пользователями"
+
+#: .\views\test.py:7
+msgid "Page in development"
+msgstr "Страница в разработке"

BIN
SharixAdmin/static/SharixAdmin/img/logo.png


File diff suppressed because it is too large
+ 0 - 6
SharixAdmin/static/SharixAdmin/img/logo.svg


+ 28 - 28
SharixAdmin/tables.py

@@ -3,16 +3,16 @@ from metaservicesynced.models import *
 from .models import *
 from django.utils.html import format_html
 from metaservicesynced.models import *
-
+from django.utils.translation import gettext_lazy as _
 
 class TransactionsWalletTable(tables.Table):
     # id = tables.Column(order_by=True)
     id = tables.Column(verbose_name='#', orderable=False,                                       attrs={"td":{"width":"5%"}})
-    wallet = tables.Column(verbose_name='Владелец', orderable=False,                            attrs={"td":{"width":"15%"}})
-    name_operation = tables.Column(verbose_name='Услуга', attrs={'th':{'scope':'col'},          "td":{"width":"20%"}}) 
-    price = tables.Column(verbose_name='Баллы', attrs={"class":"row",                           "td":{"width":"10%"}})
-    date_operation = tables.Column(verbose_name='Дата оформления',                              attrs={"td":{"width":"30%"}})
-    is_carried_out = tables.BooleanColumn(verbose_name='Статус', orderable=False, yesno="Успешно,Не успешно", attrs={"td":{"width":"20%"}})
+    wallet = tables.Column(verbose_name=_('Owner'), orderable=False,                            attrs={"td":{"width":"15%"}})
+    name_operation = tables.Column(verbose_name=_('Service'), attrs={'th':{'scope':'col'},          "td":{"width":"20%"}}) 
+    price = tables.Column(verbose_name=_('Points'), attrs={"class":"row",                           "td":{"width":"10%"}})
+    date_operation = tables.Column(verbose_name=_('Registration date'),                              attrs={"td":{"width":"30%"}})
+    is_carried_out = tables.BooleanColumn(verbose_name=_('Status'), orderable=False, yesno=_("Successful, not successful"), attrs={"td":{"width":"20%"}})
     
     class Meta:
         #model = TransactionsWallets
@@ -27,11 +27,11 @@ class TransactionsWalletTable(tables.Table):
         return format_html("<a href='{}'>{}</a>", record.get_absolute_url(), value)
         
 class PartnersTable(tables.Table):
-    id = tables.Column(verbose_name='ID', attrs={"td":{"width":"5%"}})
-    legal_name = tables.Column(verbose_name='Юрлицо', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
-    repr_id = tables.Column(accessor='repr_id.full_name', order_by=('repr_id.first_name', 'repr_id.last_name'), verbose_name='Ответственный', attrs={"td":{"width":"15%"}})
+    id = tables.Column(verbose_name=_('ID'), attrs={"td":{"width":"5%"}})
+    legal_name = tables.Column(verbose_name=_('Legal entity'), attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
+    repr_id = tables.Column(accessor='repr_id.full_name', order_by=('repr_id.first_name', 'repr_id.last_name'), verbose_name=_('Responsible'), attrs={"td":{"width":"15%"}})
    
-    status = tables.Column(verbose_name='Статус', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}}) 
+    status = tables.Column(verbose_name=_('Status'), attrs={'th':{'scope':'col'}, "td":{"width":"20%"}}) 
     check = tables.BooleanColumn(verbose_name='', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
     # paginate_by = 10
     class Meta:
@@ -50,10 +50,10 @@ class PartnersTable(tables.Table):
 
 class ResourceTable(tables.Table):
 
-    id = tables.Column(verbose_name='ID', attrs={"td":{"width":"5%"}})
+    id = tables.Column(verbose_name=_('ID'), attrs={"td":{"width":"5%"}})
     #В user_id ссылка LinkColumn на страницу Аси "Информация о партнере" страница partner_information_form
-    user_id = tables.Column(accessor='user_id.full_name', order_by=('user_id.first_name', 'user_id.last_name'), verbose_name='Ответственный', attrs={"td":{"width":"15%"}})
-    status = tables.Column(verbose_name='Статус', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}}) 
+    user_id = tables.Column(accessor='user_id.full_name', order_by=('user_id.first_name', 'user_id.last_name'), verbose_name=_('Responsible'), attrs={"td":{"width":"15%"}})
+    status = tables.Column(verbose_name=_('Status'), attrs={'th':{'scope':'col'}, "td":{"width":"20%"}}) 
     check = tables.BooleanColumn(verbose_name='', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
     # paginate_by = 10
     class Meta:
@@ -70,10 +70,10 @@ class ResourceTable(tables.Table):
 
 class ProviderTable(tables.Table):
 
-    id = tables.Column(verbose_name='ID', attrs={"td":{"width":"5%"}})
-    user_id = tables.Column(accessor='user_id.full_name', order_by=('user_id.first_name', 'user_id.last_name'), verbose_name='ФИО', attrs={"td":{"width":"15%"}})
+    id = tables.Column(verbose_name=_('ID'), attrs={"td":{"width":"5%"}})
+    user_id = tables.Column(accessor='user_id.full_name', order_by=('user_id.first_name', 'user_id.last_name'), verbose_name=_('Full Name'), attrs={"td":{"width":"15%"}})
 
-    status = tables.Column(verbose_name='Статус', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}}) 
+    status = tables.Column(verbose_name=_('Status'), attrs={'th':{'scope':'col'}, "td":{"width":"20%"}}) 
     check = tables.BooleanColumn(verbose_name='', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
     paginate_by = 10
     class Meta:
@@ -91,11 +91,11 @@ class ProviderTable(tables.Table):
 
 class ServiceTariffTable(tables.Table):
 
-    id = tables.Column(verbose_name='ID', attrs={"td":{"width":"5%"}})
-    servicetype_id = tables.LinkColumn('service_tariff/edit/', verbose_name='Название тарифа', text = lambda record: record.servicetype_id.caption,
+    id = tables.Column(verbose_name=_('ID'), attrs={"td":{"width":"5%"}})
+    servicetype_id = tables.LinkColumn('service_tariff/edit/', verbose_name=_('Name of the tariff'), text = lambda record: record.servicetype_id.caption,
         args=[tables.A('pk')], attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
-    ticket_status = tables.Column(verbose_name='Название схемы услуги', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}}) 
-    check = tables.BooleanColumn(verbose_name='Активность', orderable=False, attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
+    ticket_status = tables.Column(verbose_name=_('Name of the service scheme'), attrs={'th':{'scope':'col'}, "td":{"width":"20%"}}) 
+    check = tables.BooleanColumn(verbose_name=_('Activity'), orderable=False, attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
 
 
     class Meta:
@@ -114,7 +114,7 @@ class ServiceTariffTable(tables.Table):
 
 class ServiceTypeTable(tables.Table):
 
-    id = tables.Column(verbose_name='ID', attrs={"td":{"width":"5%"}})
+    id = tables.Column(verbose_name=_('ID'), attrs={"td":{"width":"5%"}})
     caption = tables.LinkColumn('service_type/edit/', verbose_name='Название услуги', text = lambda record: record.caption,
         args=[tables.A('pk')], attrs={'th':{'scope':'col'}, "td":{"width":"100%"},})
     deletee = tables.LinkColumn('service_type/delete/', verbose_name='', text = "Удалить",
@@ -129,24 +129,24 @@ class ServiceTypeTable(tables.Table):
                    'is_global', 'is_visible',)
 
     def render_delete(self, value, record):
-        return format_html('<a href="/service_type/delete" class="btn btn-outline-danger">Удалить</a>')
+        return format_html('<a href="/service_type/delete" class="btn btn-outline-danger">_(Delete)</a>')
         
     def render_name_operation(self, value, record):
         return format_html("<a href='{}'>{}</a>", record.get_absolute_url(), value)
    
 class ServiceTable(tables.Table):
 
-    id = tables.Column(verbose_name='ID', attrs={"td":{"width":"5%"}})
-    servicetype_id = tables.Column(verbose_name='Описание услуги (сервиса)', accessor = 'servicetype_id.caption',
+    id = tables.Column(verbose_name=_('ID'), attrs={"td":{"width":"5%"}})
+    servicetype_id = tables.Column(verbose_name=_('Description of the service'), accessor = 'servicetype_id.caption',
         attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
     
     # description = tables.Column(verbose_name='Название тарифа', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
     # description = tables.Column(verbose_name='Описание строки тарифов', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
     # price_type = tables.Column(verbose_name='Тип тарифа', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
     
-    price_km = tables.Column(verbose_name='Стоимость км.', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
-    price_min = tables.Column(verbose_name='Стоимость мин.', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
-    price_amount = tables.Column(verbose_name='Стоимость услуги', attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
+    price_km = tables.Column(verbose_name=_('Cost km.'), attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
+    price_min = tables.Column(verbose_name=_('Cost min.'), attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
+    price_amount = tables.Column(verbose_name=_('Cost of service'), attrs={'th':{'scope':'col'}, "td":{"width":"20%"}})
 
     class Meta:
         model = Service
@@ -163,7 +163,7 @@ class ServiceTable(tables.Table):
 
 class UserInfoTable(tables.Table):
 
-    id = tables.Column(verbose_name='ID', attrs={"td":{"width":"5%"}})
+    id = tables.Column(verbose_name=_('ID'), attrs={"td":{"width":"5%"}})
 
     class Meta:
         model = SharixUser

+ 37 - 0
SharixAdmin/templates/SharixAdmin/auth.html

@@ -0,0 +1,37 @@
+{% extends 'SharixAdmin/base.html' %}
+{% load i18n %}
+{% load static %}
+
+{% block content %}
+<div class="text-center" style="margin-top: 150px;">
+    <div class="form-signin" style="width: 100%; max-width:330px; margin: auto; display:block;">
+        <form class="m-2 p-2" method="post">
+            <img class="mb-4" style="height: 100px;" src="{% static 'SharixAdmin/img/logo.png' %}" alt="" >
+            <h1 class="h3 mb-3 fw-normal">{% trans 'Log in' %} в {{ NameSystem }}</h1>
+            {% csrf_token %}
+            
+            {% for item in form %}
+                <div class="form-floating my-3">
+                    {{item}}
+                    <label for="{{ item.id_for_label }}">{{ item.label }}</label>
+                </div>
+                {% if item.errors %}
+                    <div class="alert alert-danger" role="alert">
+                        {{ item.errors }}
+                    </div>
+                {% endif %}
+            {% endfor %}
+            {% if form.non_field_errors %}
+                <div class="alert alert-danger" role="alert">
+                    {% trans 'Please, enter the correct phone number and password.' %}
+                </div>
+            {% endif %}
+            <div>
+              <a class="w-100 btn btn-primary btn-lg mb-3" href="{% url 'webservice_running:registration' %}">Регистрация</a>
+              <button class=" w-100 btn btn-primary btn-lg" type="submit">{% trans 'Login' %}</button>
+            </div>
+            <p class="mt-5 mb-3 text-muted">© 2022</p>
+          </form>
+    </div>
+</div>
+{% endblock %}

+ 57 - 0
SharixAdmin/templates/SharixAdmin/balance.html

@@ -0,0 +1,57 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load i18n %}
+{% load static %}
+
+{% block contenthome %}
+    <h1 >{{ title }}</h1>
+    <div class="container" style="overflow: auto; width: 100%; height: 650px;">
+        <div class="row" >
+            <div class="col-12 text-center" >
+                <br>
+                <p>{% blocktrans trimmed %}Payment by card and bank details is available. When paying for an order with a bank card, 
+                    <br> payment processing takes place on the page of the PAYMO payment provider.{% endblocktrans %}</p>
+                <br>
+                <p>{% blocktrans trimmed %}You will need to enter your bank card details: MIR; VISA International; 
+                    <br> Mastercard Worldwide.{% endblocktrans %}</p>
+                <br>
+                <p>{% trans '3D-Secure maps only.' %}</p>
+                <form method="post" >
+                    {% csrf_token %}
+                    <div class="form-floating mb-3 w-50 m-auto">
+                        <input type="number" class="form-control" name="price" placeholder="{% trans 'Enter the required amount' %}" step="100">
+                        <label for="floatingInput">{% trans 'Enter the required amount' %}</label>
+                    </div>
+                    <br>
+                    <p>{% trans 'After replenishment, the funds can be used to pay for the services of subsidiary services.' %}</p>
+                    <br>
+                    <div>
+                        <img src="{% static 'SharixAdmin/img/visa.png' %}" alt="">
+                        <img src="{% static 'SharixAdmin/img/mc.png' %}" alt="">
+                        <img src="{% static 'SharixAdmin/img/mir.png' %}" alt="">
+                        <br>
+                        <img src="{% static 'SharixAdmin/img/paymo.png' %}" alt="">
+                    </div>
+                    <button class="btn btn-primary mt-5 mb-3">{% trans 'Replenish' %}</button>
+                    <br>
+                    <a href="" >{% trans 'Back' %}</a>
+                </form>
+            </div>
+            <div class="col-12 mt-5">
+                <h3>{% trans 'Requisites' %}</h3>
+                <div class="p-5" style="border-radius: 15px; border: solid 1px gray;">
+                  {% blocktrans trimmed %}
+                  <p>Legal address:<b>199155, the city of St. Petersburg, Zheleznovodskaya street, house 32 letter d, room 22-n office 1-8</b></p>
+                  <p>Email: <b>info@sharix-app.org </b></p>
+                  <p>TIN: <b>7801685119</b></p>
+                  <p>Bank: <b>Moscow branch of AKB MKPB (JSC)</b></p>
+                  <p>Bic: <b>044525610</b></p>
+                  <p>Current account: <b>40702810800400000025</b></p>
+                  <p>Correspondent account: <b>30101810645250000610</b></p>
+                  {% endblocktrans %}
+                </div>
+            </div>
+        </div>
+    </div>
+    
+    
+{% endblock contenthome %}

+ 10 - 0
SharixAdmin/templates/SharixAdmin/balance_success.html

@@ -0,0 +1,10 @@
+{% extends 'SharixAdmin/index.html' %}
+
+{% block contenthome %}
+    <h1 >{{ title }}</h1>
+    <div class="container text-center" style="width: 100%; height: 650px; margin-top: 250px;">
+        <h3>{{ msg }}</h3> 
+    </div>
+    
+    
+{% endblock contenthome %}

+ 18 - 0
SharixAdmin/templates/SharixAdmin/base.html

@@ -0,0 +1,18 @@
+{% load static %}
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <link rel="shortcut icon" href="{% static 'SharixAdmin/img/logo.png' %}"/>
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
+    <link type="text/css" href="{% static 'design_template/colors.css' %}" rel="stylesheet" />
+    <title>{{ title }}</title>
+</head>
+<body style="min-width: 1050px;">
+    {% block content %}
+    {% endblock %}
+    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
+</body>
+</html>

+ 163 - 0
SharixAdmin/templates/SharixAdmin/index.html

@@ -0,0 +1,163 @@
+{% extends 'SharixAdmin/base.html' %}
+{% load i18n %}
+{% load static %}
+
+{% block content %}
+<input type="checkbox" name="" style="display: none;" checked id="hideMenuCheckBox">
+<div class="container-fluid">
+    <div class="row">
+        <div class="col-3" id="leftmainpage">
+            <div class="d-flex flex-column p-2" style="width: 100%; min-width: 80px; height: 800px;  border-radius: 15px; box-shadow: 4px 5px 40px #cfcfcf; margin-top: 50px;">
+                <a class="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-decoration-none" 
+                onclick="barMenuHide()" 
+                style="cursor: pointer;">
+                  <img src="{% static 'SharixAdmin/img/menu/arrow-right.svg' %}" 
+                  style="width: 30px; height: 30px; rotate: 180deg; color: #0081ff; transition-duration: 0.4s;" 
+                  class="mx-3 my-2" id="row-bar-menu" alt="">
+                  <span class="fs-4" id="sharix-menu-row">{% trans 'ShariX Menu' %}</span>
+                </a>
+                <hr>
+                <form action="{% url 'set_language' %}" method="post">{% csrf_token %}
+                  <input name="next" type="hidden" value="{{ redirect_to }}">
+                  <select name="language">
+                      {% get_current_language as LANGUAGE_CODE %}
+                      {% get_available_languages as LANGUAGES %}
+                      {% get_language_info_list for LANGUAGES as languages %}
+                      {% for language in languages %}
+                          <option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected{% endif %}>
+                              {{ language.name_local }} ({{ language.code }})
+                          </option>
+                      {% endfor %}
+                  </select>
+                  <input type="submit" value="{% trans 'Change' %}">
+              </form>
+              <hr>
+                <ul class="nav nav-pills flex-column mb-auto">
+                  {% for item in menu %}
+                  {% if item.link == url_path %}
+                  <li class="nav-item">
+                    <a class="nav-link active" >
+                      {% with 'SharixAdmin/img/menu/'|add:item.sel|add:'_w.svg' as image_static %}
+                        <img  src="{% static image_static %}" alt="" style="width: 30px; height: 30px; "> 
+                      {% endwith %}
+                      
+                      <span class="hidemenu">{{ item.title }}</span>
+                    </a>
+                  </li>
+                  {% elif item.link == 'tickets' %}
+                  <li class="nav-item">
+                    <a href="{% url 'tickets:ticket_list_list' %}" class="nav-link" >
+                      {% with 'SharixAdmin/img/menu/'|add:item.sel|add:'.svg' as image_static %}
+                        <img  src="{% static image_static %}" alt="" style="width: 30px; height: 30px;"> 
+                      {% endwith %}
+                      <span class="hidemenu">{{ item.title }}</span>
+                    </a>
+                  </li>
+                  {% elif item.link == 'course' %}
+                  <li class="nav-item">
+                    <a href="http://study.reversea.net/" class="nav-link" >
+                      {% with 'SharixAdmin/img/menu/'|add:item.sel|add:'.svg' as image_static %}
+                        <img  src="{% static image_static %}" alt="" style="width: 30px; height: 30px;"> 
+                      {% endwith %}
+                      <span class="hidemenu">{{ item.title }}</span>
+                    </a>
+                  </li>
+                  {% else %}
+                  <li class="nav-item">
+                    <a href="{% url item.link %}" class="nav-link" >
+                      {% with 'SharixAdmin/img/menu/'|add:item.sel|add:'.svg' as image_static %}
+                        <img  src="{% static image_static %}" alt="" style="width: 30px; height: 30px; "> 
+                      {% endwith %}
+                      <span class="hidemenu">{{ item.title }}</span>
+                    </a>
+                  </li>
+                  {% endif%}
+                  {% endfor %}
+                </ul>
+                <hr>
+                <div class="dropdown">
+                  <a href="#" class="d-flex align-items-center link-dark text-decoration-none dropdown-toggle" id="dropdownUser2" data-bs-toggle="dropdown" aria-expanded="false">
+                    <img alt="" width="32" height="32" class="rounded-circle me-2">
+                    <strong id="user-name-exit">{{ request.user.username }}</strong>
+                  </a>
+                  <ul class="dropdown-menu text-small shadow" aria-labelledby="dropdownUser2">
+                    <li><a class="dropdown-item" href="#">{% trans 'Contacts' %}Контакты</a></li>
+                    <li><a class="dropdown-item" href="#">{% trans 'Terms of use' %}</a></li>
+                    <li><a class="dropdown-item" href="#">{% trans 'Privacy policy' %}</a></li>
+                    <li><hr class="dropdown-divider"></li>
+                    <li><a class="btn btn-danger mx-2" href="{% url 'logoutweb' %}">{% trans 'Log out' %}</a></li>
+                  </ul>
+                </div>
+              </div>      
+        </div>
+        <div class="col-9" id="rightmainpage">
+            <div class="d-flex flex-column p-4" 
+            style="
+            width: 100%; 
+            height: 800px; 
+            border-radius: 15px; 
+            background-color:white;
+            box-shadow: 4px 5px 40px #cfcfcf; 
+            margin-top: 50px;">
+            {% block contenthome %}
+            {% endblock contenthome%}
+        </div>
+            
+        </div>
+    </div>
+</div>
+
+<script>
+  hidemenu = document.getElementsByClassName('hidemenu')
+  shMenuRow = document.getElementById('sharix-menu-row')
+  usNameExit = document.getElementById('user-name-exit')
+  rightmainpage = document.getElementById('rightmainpage')
+  leftmainpage = document.getElementById('leftmainpage')
+  hideCheck = document.getElementById('hideMenuCheckBox')
+  rowBarMenu = document.getElementById('row-bar-menu')
+
+  function show(){
+    rowBarMenu.style.transform = 'rotate(0deg)';
+    shMenuRow.style.display = "inline"
+      usNameExit.style.display = "inline"
+      leftmainpage.style.maxWidth = "unset"
+      leftmainpage.classList.remove("col-1")
+      leftmainpage.classList.add("col-3")
+      rightmainpage.classList.remove("col-11")
+      rightmainpage.classList.add("col-9")
+      for(var i = 0; i < hidemenu.length; i++){
+       hidemenu[i].style.display = "inline"; // depending on what you're doing
+      }
+  }
+  function hide(){
+    rowBarMenu.style.transform = 'rotate(180deg)';
+    shMenuRow.style.display = "none"
+    usNameExit.style.display = "none"
+    leftmainpage.style.maxWidth = "100px"
+    leftmainpage.classList.remove("col-3")
+    leftmainpage.classList.add("col-1")
+    rightmainpage.classList.remove("col-9")
+    rightmainpage.classList.add("col-11")
+    for(var i = 0; i < hidemenu.length; i++){
+      hidemenu[i].style.display = "none"; // depending on what you're doing
+    }
+  }
+  function barMenuHide(){
+    if(hideCheck.checked == true){
+      hideCheck.checked = false
+      hide()
+    } else {
+      hideCheck.checked = true
+      show()
+    }
+  }
+  if(hideCheck.checked == true){
+      show()
+    } else {
+      hide()
+    }
+  
+  
+</script>
+
+{% endblock %}

+ 38 - 0
SharixAdmin/templates/SharixAdmin/main.html

@@ -0,0 +1,38 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load i18n %}
+
+{% block contenthome %}
+    <h1 >{{ title }}</h1>
+    <div class="container" style="padding: 2px;">
+        <div class="row fs-6">
+            
+            <div class="col-6 ">
+                <ul class="list-group">
+                    <li class="list-group-item light"><strong>{% trans 'Documentation' %}</strong> </li>
+                    <li class="list-group-item"><a  href="https://wiki.sharix-app.org/doku.php/sharix/legal/politika_konfidencialnosti_platformy_sharix">{% trans 'Privacy policy' %}</a></li>
+                    <li class="list-group-item"><a  href="https://wiki.sharix-app.org/doku.php/sharix/legal/pravila_okazanija_uslug">{% trans 'Rules for the provision of services' %}</a></li>
+                    <li class="list-group-item"><a  href="https://wiki.sharix-app.org/doku.php/sharix/legal/porjadok_okazanija_uslug">{% trans 'Procedure for the provision of services' %}</a></li>
+                    <li class="list-group-item"><a  href="https://wiki.sharix-app.org/doku.php/sharix/legal/perechen_uslug_platformy">{% trans 'List of services' %}</a></li>
+                    <li class="list-group-item"><a  href="{% url 'schemav1' %}">{% trans 'Scheme 1' %}</a> / <a  href="{% url 'schemav2' %}">{% trans 'Scheme 2' %}</a> / <a  href="{% url 'schema' %}">{% trans 'Scheme 3' %}</a> / <a  href="{% url 'schema-redoc' %}">{% trans 'API Docs' %}</a></li>
+                
+                  </ul>
+            </div>
+            <div class="col-6 text-end">
+              {% blocktrans trimmed with request.user.username as user %}
+              <p>User: <b>{{ user }}</b></p>
+              {% endblocktrans %}
+              {% blocktrans trimmed %}
+              <p>Phone number: <b>{{ phone }}</b></p>
+              {% endblocktrans %}
+              {% blocktrans trimmed with request.user.date_joined as date %}
+              <p>Date of registration: <b>{{ date }}</b></p>
+              {% endblocktrans %}
+              {% blocktrans trimmed with wallet.balance as balance %}
+              <p>Balance: <b>{{ balance }} points</b></p>
+              {% endblocktrans %}
+                <a href="{% url 'balance' %}" class="btn btn-success">{% trans 'Buy points' %}</a>
+            </div>
+        </div>
+    </div>
+    
+{% endblock contenthome %}

+ 22 - 0
SharixAdmin/templates/SharixAdmin/partner_information_form.html

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

+ 38 - 0
SharixAdmin/templates/SharixAdmin/partners.html

@@ -0,0 +1,38 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load render_table from django_tables2 %}
+
+{% 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 partners_id = $(this).data('partners-id');
+        var new_status = $(this).prop('checked') ? 'active' : 'deactivated';
+        $.ajax({
+          url: '{% url "partners/change_status" %}',
+          type: 'POST',
+          data: {
+            'partners_id': partners_id,
+            '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 %}

+ 38 - 0
SharixAdmin/templates/SharixAdmin/provider.html

@@ -0,0 +1,38 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load render_table from django_tables2 %}
+
+{% 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 provider_id = $(this).data('provider-id');
+        var new_status = $(this).prop('checked') ? 'active' : 'deactivated';
+        $.ajax({
+          url: '{% url "provider/change_status" %}',
+          type: 'POST',
+          data: {
+            'provider_id': provider_id,
+            '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 %}

+ 38 - 0
SharixAdmin/templates/SharixAdmin/resource.html

@@ -0,0 +1,38 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load render_table from django_tables2 %}
+
+{% 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_id = $(this).data('resource-id');
+        var new_status = $(this).prop('checked') ? 'active' : 'deactivated';
+        $.ajax({
+          url: '{% url "resource/change_status" %}',
+          type: 'POST',
+          data: {
+            'resource_id': resource_id,
+            '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 %}

+ 10 - 0
SharixAdmin/templates/SharixAdmin/schema.html

@@ -0,0 +1,10 @@
+{% extends 'SharixAdmin/base.html' %}
+{% load static %}
+
+{% block content %}
+    
+     <div class="container-fluid" style="width: 100%;" >
+        <img src="{% static 'SharixAdmin/img/schemav3.png' %}" /> 
+    </div> 
+    
+{% endblock content %}

+ 12 - 0
SharixAdmin/templates/SharixAdmin/senderform.html

@@ -0,0 +1,12 @@
+{% extends "admin/base_site.html" %}
+{% load i18n %}
+
+{% block content %}
+<form action="" method="post">{% csrf_token %}
+    {{ form }}
+    <p>{% trans 'The message will be sent to the following users:' %}</p>
+    <ul>{{ items|unordered_list }}</ul>
+    <input type="hidden" name="action" value="{% trans 'send_phone' %}" />
+    <input type="submit" name="apply" value="{% trans 'Submit' %}" />
+</form>
+{% endblock %}

+ 38 - 0
SharixAdmin/templates/SharixAdmin/service.html

@@ -0,0 +1,38 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load render_table from django_tables2 %}
+
+{% 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 service_id = $(this).data('service-id');
+        var new_status = $(this).prop('checked') ? 'active' : 'deactivated';
+        $.ajax({
+          url: '{% url "service/change_status" %}',
+          type: 'POST',
+          data: {
+            'service_id': service_id,
+            '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 %}

+ 26 - 0
SharixAdmin/templates/SharixAdmin/service_information_form.html

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

+ 49 - 0
SharixAdmin/templates/SharixAdmin/service_tariff.html

@@ -0,0 +1,49 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load render_table from django_tables2 %}
+{% load i18n %}
+
+{% block contenthome %}
+    <h1 >{{ title }}</h1>
+    <div class="container text-center mt-2">
+          {% render_table table %}
+
+          {% comment %} {% if table.page %}
+            <nav aria-label="...">
+              <ul class="pagination">
+                {% if table.page.has_previous %}
+                <li class="page-item">
+                  <a class="page-link" href="?page={{ table.page.previous_page_number }}" tabindex="-1">{% trans 'Previous' %}</a>
+                </li>
+                {% else %}
+                <li class="page-item disabled">
+                  <span class="page-link">{% trans 'Previous' %}</span>
+                </li>
+                {% endif %}
+                {% for page in table.page_range %}
+                  {% if page == table.page.number %}
+                  <li class="page-item active">
+                    <span class="page-link">{{ page }} <span class="sr-only">{% trans '(current)' %}</span></span>
+                  </li>
+                  {% else %}
+                  <li class="page-item">
+                    <a class="page-link" href="?page={{page }}">{{ page }}</a>
+                  </li>
+                  {% endif %}
+                {% endfor %}
+                {% if table.page.has_next %}
+                <li class="page-item">
+                  <a class="page-link" href="?page={{ table.page.next_page_number }}">{% trans 'Next' %}</a>
+                </li>
+                {% else %}
+                <li class="page-item disabled">
+                  <span class="page-link">{% trans 'Next' %}</span>
+                </li>
+                {% endif %}
+              </ul>
+            </nav>
+          {% endif %} {% endcomment %}
+    </div>
+    <div class="container text-end mt-2">
+      <a class="btn btn-primary" href="/service_tariff/add">{% trans 'Add' %}</a>
+    </div>
+{% endblock contenthome %}

+ 22 - 0
SharixAdmin/templates/SharixAdmin/service_tariff_form.html

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

+ 49 - 0
SharixAdmin/templates/SharixAdmin/service_type.html

@@ -0,0 +1,49 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load render_table from django_tables2 %}
+{% load i18n %}
+
+{% block contenthome %}
+    <h1 >{{ title }}</h1>
+    <div class="container text-center mt-2">
+          {% render_table table %}
+
+          {% comment %} {% if table.page %}
+            <nav aria-label="...">
+              <ul class="pagination">
+                {% if table.page.has_previous %}
+                <li class="page-item">
+                  <a class="page-link" href="?page={{ table.page.previous_page_number }}" tabindex="-1">{% trans 'Previous' %}</a>
+                </li>
+                {% else %}
+                <li class="page-item disabled">
+                  <span class="page-link">{% trans 'Previous' %}</span>
+                </li>
+                {% endif %}
+                {% for page in table.page_range %}
+                  {% if page == table.page.number %}
+                  <li class="page-item active">
+                    <span class="page-link">{{ page }} <span class="sr-only">{% trans '(current)' %}</span></span>
+                  </li>
+                  {% else %}
+                  <li class="page-item">
+                    <a class="page-link" href="?page={{page }}">{{ page }}</a>
+                  </li>
+                  {% endif %}
+                {% endfor %}
+                {% if table.page.has_next %}
+                <li class="page-item">
+                  <a class="page-link" href="?page={{ table.page.next_page_number }}">{% trans 'Next' %}</a>
+                </li>
+                {% else %}
+                <li class="page-item disabled">
+                  <span class="page-link">{% trans 'Next' %}</span>
+                </li>
+                {% endif %}
+              </ul>
+            </nav>
+          {% endif %} {% endcomment %}
+    </div>
+    <div class="container text-end mt-2">
+      <a class="btn btn-primary" href="/service_type/add">{% trans 'Add' %}</a>
+    </div>
+{% endblock contenthome %}

+ 15 - 0
SharixAdmin/templates/SharixAdmin/service_type_delete.html

@@ -0,0 +1,15 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load i18n %}
+
+{% block contenthome %}
+<h1 class="mb-4">{{ title }}</h1>
+<form method="post">
+    {% csrf_token %}
+    <div class="container m-2">
+        <p>{% blocktrans %}Are you sure you want to delete \"%(object.caption)s\"?{% endblocktrans %}</p>
+    </div>
+    <div class="text-center mt-2 mb-5">
+        <input class="btn btn-primary center" type="submit" name="apply" value="{% trans 'Delete' %}"/>
+    </div>
+</form>
+{% endblock %}

+ 22 - 0
SharixAdmin/templates/SharixAdmin/service_type_form.html

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

+ 10 - 0
SharixAdmin/templates/SharixAdmin/test.html

@@ -0,0 +1,10 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load i18n %}
+
+{% block contenthome %}
+    <h1 >{{ title }}</h1>
+    <div class="container text-center" style="width: 100%; height: 650px; margin-top: 250px;">
+        <h3>{% trans 'These pages are under development' %}</h3> 
+    </div>
+    
+{% endblock contenthome %}

+ 26 - 0
SharixAdmin/templates/SharixAdmin/trans_carried.html

@@ -0,0 +1,26 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load i18n %}
+
+{% block contenthome %}
+    <h1 >{{ title }}</h1>
+    <h3 >{% trans 'User: ' %}{{ request.user.username }}</h3>
+    <h3 >{% trans 'Balance: ' %}{{ wallet.balance }} р.</h3>
+    {% if balance_err %}
+    <div class="alert alert-danger" role="alert">
+        {{ balance_err }}
+    </div>
+    {% endif %}
+    <ul class="list-group">
+        <li class="list-group-item active">{{ model.name_operation }}</li>
+        <li class="list-group-item">{% trans 'Price: ' %}{{ model.price }}</li>
+        <li class="list-group-item">{% trans 'Owner: ' %}{{ model.wallet.user.username }}</li>
+        <li class="list-group-item">{% trans 'Date of service: ' %}{{ model.date_operation }}</li>
+        <li class="list-group-item">{% trans 'Conducted: ' %}{{ model.is_carried_out }}</li>
+    </ul>
+    {% if not model.is_carried_out %}
+    <form method="post">
+        {% csrf_token %}
+        <button class="btn btn-success my-3" type="submit">{% trans 'Spend' %}</button>
+    </form>
+    {% endif %}
+{% endblock contenthome %}

+ 16 - 0
SharixAdmin/templates/SharixAdmin/transactions.html

@@ -0,0 +1,16 @@
+{% extends 'SharixAdmin/index.html' %}
+{% load render_table from django_tables2 %}
+{% load i18n %}
+
+{% block contenthome %}
+    <h1 >{{ title }}</h1>
+    <h3 >{% trans 'User: ' %}{{ request.user.username }}</h3>
+    <h3 >{% blocktrans %}Balance: {{ wallet.balance }} points{% endblocktrans %}</h3>
+    <form class="d-flex" method="post">
+        {% csrf_token %}
+        <input class="form-control me-2" name="search" type="search" placeholder="{% trans 'Search' %}" aria-label="Search">
+        <button class="btn btn-outline-success" type="submit">{% trans 'Search' %}</button>
+      </form>
+      {% comment %} {% render_table  table %} {% endcomment %}
+{% endblock contenthome %} 
+

+ 3 - 2
SharixAdmin/urls.py

@@ -44,7 +44,8 @@ urlpatterns = [
     
     path('service/', ServiceListView.as_view(), name='service'),
     path('service/change_status/', change_service_status, name='service/change_status'),
-    
+
+    path('partner_information/', login_required(PartnerInfoView.as_view()), name='partner_information/'),    
     path('partner_information/add/', login_required(PartnerInformationCreate.as_view()), name='partner_information/add/'),
     path('partner_information/edit/<int:pk>', login_required(PartnerInformationUpdateView.as_view()), name='partner_information/edit/'),
 
@@ -61,4 +62,4 @@ urlpatterns = [
     path('schemav3/', schema_v3, name='schema'),
     
     re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
-]
+]

+ 6 - 5
SharixAdmin/views/balance.py

@@ -1,23 +1,24 @@
 from django.shortcuts import render
 from django.contrib.auth.decorators import login_required
 from SharixAdmin.views.context import get_context
+from django.utils.translation import gettext as _
 
 @login_required
 def balance(request):
     context = get_context(request, {
-        'title':'Пополнить баланс'
+        'title':_('Top up your balance')
         })
     if request.method == 'POST':
         if float(request.POST['price']) > 0:
             context = get_context(request, {
-                'title':'Пополнить баланс',
-                'msg':'Оплата прошла успешно ;)'
+                'title':_('Top up your balance'),
+                'msg':_('The payment was successful ;)')
                 })
             return render(request, "SharixAdmin/balance_success.html", context)
         else:
             context = get_context(request, {
-                'title':'Пополнить баланс',
-                'msg':'Оплата не прошла ;('
+                'title':_('Top up your balance'),
+                'msg':_('Payment failed ;(')
                 })
             return render(request, "SharixAdmin/balance_success.html", context)
 

+ 20 - 19
SharixAdmin/views/context.py

@@ -1,33 +1,34 @@
 from django.urls import resolve
+from django.utils.translation import gettext_lazy as _
 
 menu = [
-    {'title':'Главная/баланс',          'link':'home', 'sel':'house'},
-    {'title':'Платежная информация',    'link':'test-page', 'sel':'credit-card'},
-    {'title':'История платежей',        'link':'trans','sel':'clock-history'},
-    {'title':'Курсы',                   'link':'course', 'sel':'education'},
-    {'title':'Личная информация',       'link':'test-page', 'sel':'person'},
-    {'title':'Управление сервисами',    'link':'test-page', 'sel':'hdd-network'},
-    {'title':'Мои связи',               'link':'test-page', 'sel':'people'},
-    {'title':'Сотрудничество',          'link':'test-page', 'sel':'sotrud'},
-    {'title':'Техподдержка',            'link':'test-page', 'sel':'gear'},
-    {'title':'Мои заявки',              'link':'tickets', 'sel':'tikets'},
-    {'title':'Исполнители',             'link':'provider', 'sel':'people', 
+    {'title':_('Home/Balance'),          'link':'home', 'sel':'house'},
+    {'title':_('Payment information'),    'link':'test-page', 'sel':'credit-card'},
+    {'title':_('Payment history'),        'link':'trans','sel':'clock-history'},
+    {'title':_('Courses'),                   'link':'course', 'sel':'education'},
+    {'title':_('Personal information'),       'link':'test-page', 'sel':'person'},
+    {'title':_('Service management'),    'link':'test-page', 'sel':'hdd-network'},
+    {'title':_('My connections'),               'link':'test-page', 'sel':'people'},
+    {'title':_('Partnership'),          'link':'test-page', 'sel':'sotrud'},
+    {'title':_('Techsupport'),            'link':'test-page', 'sel':'gear'},
+    {'title':_('My tickets'),              'link':'tickets', 'sel':'tikets'},
+    {'title':_('Performers'),             'link':'provider', 'sel':'people', 
      'roles':['METASERVICE-ADMIN']},
-    {'title':'Тарифы услуг',            'link':'service_tariff', 'sel':'person',
+    {'title':_('Service rates'),            'link':'service_tariff', 'sel':'person',
      'roles':['PARTNER-ADMIN']},
-    {'title':'Партнеры',                'link':'partners', 'sel':'people',
+    {'title':_('Partners'),                'link':'partners', 'sel':'people',
      'roles':['METASERVICE-ADMIN']},
-    {'title':'Ресурсы',                 'link':'resource', 'sel':'sotrud',
+    {'title':_('Resources'),                 'link':'resource', 'sel':'sotrud',
      'roles':['PARTNER-ADMIN']},
-    {'title':'Услуги сервиса',          'link':'service_type', 'sel':'hdd-network',
+    {'title':_('Service services'),          'link':'service_type', 'sel':'hdd-network',
      'roles':['METASERVICE-ADMIN']},
-    {'title':'Информация о сервисе',    'link':'service_information/add/', 'sel':'hdd-network',
+    {'title':_('Information about the service'),    'link':'service_information/add/', 'sel':'hdd-network',
      'roles':['METASERVICE-ADMIN']},
-    {'title':'Информация о партнере',   'link':'partner_information/add/', 'sel':'person',
+    {'title':_('Partner Information'),   'link':'partner_information/', 'sel':'person',
      'roles':['PARTNER-ADMIN']},
-    {'title':'Тарифы',                  'link':'service', 'sel':'tikets',
+    {'title':_('Rates'),                  'link':'service', 'sel':'tikets',
      'roles':['PARTNER-ADMIN']},
-    {'title':'Управление пользователями','link':'user_information', 'sel':'person'}
+    {'title':_('User Management'),'link':'user_information', 'sel':'person'}
 ]
 
 def get_context(request, page_context) -> dict:

+ 3 - 1
SharixAdmin/views/index.py

@@ -1,6 +1,8 @@
 from django.contrib.auth.decorators import login_required
 from SharixAdmin.views.context import get_context
 from django.shortcuts import render
+from django.utils.translation import gettext as _
+
 
 @login_required
 def index(request):
@@ -9,7 +11,7 @@ def index(request):
     convert_ph_num = f"+{ph_num[:1]} ({ph_num[1:4]}) {ph_num[4:7]}-{ph_num[7:9]}-{ph_num[9:11]}"
     #print(convert_ph_num)
     context = get_context(request, {
-        'title':'Главная/баланс',
+        'title':_('Home/Balance'),
         'phone':convert_ph_num
     })
     

+ 120 - 5
SharixAdmin/views/partner_info.py

@@ -6,22 +6,52 @@ from django.contrib.auth.mixins import UserPassesTestMixin
 from django.views.generic.edit import UpdateView, CreateView
 from SharixAdmin.views.context import get_context
 from django.urls import reverse
+from django.utils.translation import gettext as _
+
+from core.utils.AuthAPI import AuthAPI
+from tickets.models import Ticket
+from core.settings import API_URL
+api = AuthAPI("79999999999", "Pa$$w0rd1")
+import requests
+from django.urls import reverse_lazy
+from django.contrib.auth.hashers import check_password
+
+import xmpp
+from xmpp import cli
 
 class PartnerInformationCreate(UserPassesTestMixin, CreateView):
     model = Company
     form_class = PartnerInformationCreateForm
     template_name = "SharixAdmin/partner_information_form.html"
+    success_url = reverse_lazy("SharixAdmin:partners")
+
+    def form_valid(self, form):
+        form.instance.representative_id = self.request.user
+        new_ticket = {
+            "task_list": 1,
+            "created_by": self.request.user.pk,
+            "type": 1,
+            "title": "service_create",
+            "note": str(form.data),
+        }
+        resp = requests.post(f"{API_URL}/tickets/api/tickets/", data=new_ticket, headers=api.headers)
+        jso = resp.json()
+        form.instance.ticket_status = Ticket.objects.get(pk=int(jso['id']))
+        print(form.cleaned_data)
+        responce = super().form_valid(form)
+        cli.send_message("open_tickets_backend@ej.sharix-app.org", "eb177b1c9f99a7a13798928318d7a72c", "open_strequest_new@ej.sharix-app.org", str(jso))
+        return responce
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Информация о партнере',
+            'title': _('Partner Information'),
             'object': self.object,
         }))
         return context
     
     def get_success_url(self):
-        return reverse('test-page')
+        return reverse('partners')
     
     def test_func(self) -> bool or None:
         group_names = ('PARTNER-ADMIN')
@@ -35,13 +65,41 @@ class PartnerInformationUpdateView(UserPassesTestMixin, UpdateView):
     template_name = "SharixAdmin/partner_information_form.html"
 
     def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
+        context = super().get_context_data(**kwargs)       
         context.update(get_context(self.request, {
-            'title': 'Информация о партнере',
+            'title': _('Partner Information'),
             'object': self.object,
         }))
         return context
     
+    def form_valid(self, form):
+        # Получаем текущий объект Company
+        self.object = form.save()
+
+        # Проверяем, изменились ли поля inn, ogrn, kpp, ответственный, название
+        if (self.object.inn != form.initial['inn'] or
+            self.object.ogrn != form.initial['ogrn'] or
+            self.object.kpp != form.initial['kpp'] or
+            self.object.repr_id != form.initial['repr_id'] or
+            self.object.legal_name != form.initial['legal_name']):
+            new_ticket = {
+            "ticket_list": 1,
+            "created_by": self.request.user.pk,
+            "type": 1,
+            "title": "service_update",
+            "note": str(form.data),
+            }
+            resp = requests.post(f"{API_URL}/tickets/api/tickets/", data=new_ticket, headers=api.headers)
+            jso = resp.json()
+            form.instance.ticket_status = Ticket.objects.get(pk=int(jso['id']))
+            print(form.cleaned_data)
+            cli.send_message("open_tickets_backend@ej.sharix-app.org", "eb177b1c9f99a7a13798928318d7a72c", "open_strequest_new@ej.sharix-app.org", str(jso))
+            self.object.status = "deactivate"
+            responce = super().form_valid(form)
+            return responce
+        else:
+            return super().form_valid(form)
+
     def get_success_url(self):
         return reverse('test-page')
     
@@ -50,10 +108,67 @@ class PartnerInformationUpdateView(UserPassesTestMixin, UpdateView):
         if bool(self.request.user.groups.filter(name=group_names)) or self.request.user.is_superuser:
             return True
         return False
+
+class PartnerInfoView(UserPassesTestMixin, UpdateView):
+    model = Company
+    form_class = PartnerInformationUpdateForm
+    template_name = "SharixAdmin/partner_information_form.html"
+
+    def get_context_data(self, **kwargs):
+        # Проверяем, был ли ранее создан объект Company текущим пользователем
+        if self.request.user.is_authenticated:
+            company = Company.objects.filter(repr_id=self.request.user).first()
+            if company:
+                context['object'] = company
+            
+        context = super().get_context_data(**kwargs)       
+        context.update(get_context(self.request, {
+            'title': _('Partner Information'),
+            'object': self.object,
+        }))
+        return context
+    
+    def form_valid(self, form):
+        # Получаем текущий объект Company
+        self.object = form.save()
+
+        # Проверяем, изменились ли поля inn, ogrn, kpp, ответственный, название
+        if (self.object.inn != form.initial['inn'] or
+            self.object.ogrn != form.initial['ogrn'] or
+            self.object.kpp != form.initial['kpp'] or
+            self.object.repr_id != form.initial['repr_id'] or
+            self.object.legal_name != form.initial['legal_name']):
+            new_ticket = {
+            "ticket_list": 1,
+            "created_by": self.request.user.pk,
+            "type": 1,
+            "title": "service_update",
+            "note": str(form.data),
+            }
+            resp = requests.post(f"{API_URL}/tickets/api/tickets/", data=new_ticket, headers=api.headers)
+            jso = resp.json()
+            form.instance.ticket_status = ticket.objects.get(pk=int(jso['id']))
+            print(form.cleaned_data)
+            cli.send_message("open_tickets_backend@ej.sharix-app.org", "eb177b1c9f99a7a13798928318d7a72c", "open_strequest_new@ej.sharix-app.org", str(jso))
+            self.object.status = "deactivate"
+            responce = super().form_valid(form)
+            return responce
+        else:
+            return super().form_valid(form)
+
+    def get_success_url(self):
+        return reverse('test-page')
     
+    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
+
+
 def partner_information(request):
     context = get_context(request, {
-        'title':'Информация о партнере',
+        'title':_('Partner Information'),
         })
     
     return render(request, 'SharixAdmin/partner_information.html', context)

+ 3 - 1
SharixAdmin/views/partners.py

@@ -6,6 +6,8 @@ from django.contrib.auth.decorators import login_required
 from metaservicesynced.models import Company
 from SharixAdmin.views.context import get_context
 from django.http import JsonResponse
+from django.utils.translation import gettext as _
+
 
 class PartnersListView(UserPassesTestMixin, SingleTableView):
     table_class = PartnersTable
@@ -15,7 +17,7 @@ class PartnersListView(UserPassesTestMixin, SingleTableView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Партнеры',
+            'title': _('Partners'),
             'object_list': context['object_list'],
         }))
         return context

+ 2 - 1
SharixAdmin/views/provider.py

@@ -6,6 +6,7 @@ from django.contrib.auth.decorators import login_required
 from SharixAdmin.views.context import get_context
 from django.http import JsonResponse
 from django.contrib.auth.mixins import UserPassesTestMixin
+from django.utils.translation import gettext as _
 
 class ProviderListView(UserPassesTestMixin, SingleTableView):
     table_class = ProviderTable
@@ -15,7 +16,7 @@ class ProviderListView(UserPassesTestMixin, SingleTableView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Исполнители',
+            'title': _('Performers'),
             'object_list': context['object_list'],
         }))
         return context

+ 2 - 1
SharixAdmin/views/resource.py

@@ -6,6 +6,7 @@ from django.contrib.auth.decorators import login_required
 from metaservicesynced.models import Resource
 from SharixAdmin.views.context import get_context
 from django.http import JsonResponse
+from django.utils.translation import gettext as _
 
 class ResourceListView(UserPassesTestMixin, SingleTableView):
     table_class = ResourceTable
@@ -15,7 +16,7 @@ class ResourceListView(UserPassesTestMixin, SingleTableView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Ресурсы',
+            'title': _('Resources'),
             'object_list': context['object_list'],
         }))
         return context

+ 2 - 1
SharixAdmin/views/service.py

@@ -5,6 +5,7 @@ from metaservicesynced.models import Service
 from django.contrib.auth.decorators import login_required
 from SharixAdmin.views.context import get_context
 from django.contrib.auth.mixins import UserPassesTestMixin
+from django.utils.translation import gettext as _
 
 class ServiceListView(UserPassesTestMixin, SingleTableView):
     table_class = ServiceTable
@@ -14,7 +15,7 @@ class ServiceListView(UserPassesTestMixin, SingleTableView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Тарифы',
+            'title': _('Rates'),
             'object_list': context['object_list'],
         }))
         return context

+ 33 - 3
SharixAdmin/views/service_info.py

@@ -4,23 +4,53 @@ from django.views.generic.edit import CreateView, UpdateView
 from metaservicesynced.models import Service
 from SharixAdmin.views.context import get_context
 from django.urls import reverse
+from django.utils.translation import gettext as _
+
+from core.utils.AuthAPI import AuthAPI
+from tickets.models import Ticket
+from core.settings import API_URL
+api = AuthAPI("89855703300", "12345")
+import requests
+from django.urls import reverse_lazy
+from datetime import timezone
+import xmpp
+from xmpp import cli
 
 class ServiceInformationCreate(UserPassesTestMixin, CreateView):
     model = Service
     form_class = ServiceInformationCreateForm
     template_name = "SharixAdmin/service_information_form.html"
+    success_url = reverse_lazy("SharixAdmin:service_tariff")
+
+    def form_valid(self, form):
+        new_ticket = {
+            "ticket_list": 1,
+            "created_by": self.request.user.pk,
+            "type": 1,
+            "title": "service_create",
+            "note": str(form.data),
+        }
+        resp = requests.post(f"{API_URL}/tickets/api/tickets/", data=new_ticket, headers=api.headers)
+        jso = resp.json()
+        form.instance.ticket_status = Ticket.objects.get(pk=int(jso['id']))
+        print(form.cleaned_data)
+        responce = super().form_valid(form)
+        cli.send_message("open_tickets_backend@ej.sharix-app.org", "eb177b1c9f99a7a13798928318d7a72c", "open_strequest_new@ej.sharix-app.org", str(jso))
+        return responce
+
 
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Информация о сервисе',
+            'title': _('Information about the service'),
             'object': self.object,
             
         }))
         return context
     
     def get_success_url(self):
-        return reverse('test-page')
+        return reverse('service_tariff')
+    
     
     def test_func(self) -> bool or None:
         group_names = ('METASERVICE-ADMIN')
@@ -36,7 +66,7 @@ class ServiceInformationUpdateView(UserPassesTestMixin, UpdateView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Информация о сервисе',
+            'title': 'Information about the service',
             'object': self.object,
         }))
         return context

+ 4 - 3
SharixAdmin/views/service_tariff.py

@@ -6,6 +6,7 @@ from SharixAdmin.forms import ServiceTariffCreateForm, ServiceTariffUpdateForm
 from metaservicesynced.models import Service
 from django.urls import reverse
 from SharixAdmin.views.context import get_context
+from django.utils.translation import gettext as _
 
 class ServiceTariffCreate(UserPassesTestMixin, CreateView):
     model = Service
@@ -15,7 +16,7 @@ class ServiceTariffCreate(UserPassesTestMixin, CreateView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Тарифы услуг',
+            'title': _('Service rates'),
             'object': self.object,
         }))
         return context
@@ -37,7 +38,7 @@ class ServiceTariffListView(UserPassesTestMixin, SingleTableView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Исполнители',
+            'title': _('Performers'),
             'object_list': context['object_list'],
         }))
         return context
@@ -57,7 +58,7 @@ class ServiceTariffUpdateView(UserPassesTestMixin, UpdateView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Тарифы услуг',
+            'title': _('Service rates'),
             'object': self.object,
         }))
         return context

+ 5 - 4
SharixAdmin/views/service_type.py

@@ -6,6 +6,7 @@ from SharixAdmin.forms import ServiceTypeCreateForm, ServiceTypeUpdateForm
 from metaservicesynced.models import ServiceType
 from django.urls import reverse
 from SharixAdmin.views.context import get_context
+from django.utils.translation import gettext as _
 
 class ServiceTypeCreate(UserPassesTestMixin, CreateView):
     model = ServiceType
@@ -15,7 +16,7 @@ class ServiceTypeCreate(UserPassesTestMixin, CreateView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Услуги сервиса',
+            'title': _('Service services'),
             'object': self.object,
         }))
         return context
@@ -38,7 +39,7 @@ class ServiceTypeListView(UserPassesTestMixin, SingleTableView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Услуги сервиса',
+            'title': 'Service services',
             'object_list': context['object_list'],
         }))
         return context
@@ -57,7 +58,7 @@ class ServiceTypeUpdateView(UserPassesTestMixin, UpdateView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Услуги сервиса',
+            'title': 'Service services',
             'object_list': context['object_list'],
         }))
         return context
@@ -76,7 +77,7 @@ class ServiceTypeDelete(UserPassesTestMixin, DeleteView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Услуги сервиса',
+            'title': 'Service services',
             'object': self.object,
         }))
         return context

+ 2 - 1
SharixAdmin/views/test.py

@@ -1,8 +1,9 @@
 from SharixAdmin.views.context import get_context
 from django.shortcuts import render
+from django.utils.translation import gettext as _
 
 def testPage(request):
     context = get_context(request, {
-        'title':'Страница в разработке'
+        'title':_('Page in development')
         })
     return render(request, "SharixAdmin/test.html", context)

+ 2 - 1
SharixAdmin/views/trans_id.py

@@ -1,10 +1,11 @@
 from django.shortcuts import render
 from SharixAdmin.views.context import get_context
 from django.contrib.auth.decorators import login_required
+from django.utils.translation import gettext as _
 
 @login_required
 def trans_id(request, trans_id):
     context = get_context(request, {
-        'title':'Услуга'
+        'title':_('Service')
         })
     return render(request, 'SharixAdmin/trans_carried.html', context)

+ 2 - 1
SharixAdmin/views/transactions.py

@@ -1,12 +1,13 @@
 from django.contrib.auth.decorators import login_required
 from SharixAdmin.views.context import get_context
 from django.shortcuts import render
+from django.utils.translation import gettext as _
 
 @login_required
 def transactions(request):
     
     context = get_context(request, {
-        'title':'История платежей',
+        'title':_('Payment history'),
         })
         
     return render(request, 'SharixAdmin/transactions.html', context)

+ 2 - 1
SharixAdmin/views/user_info.py

@@ -4,6 +4,7 @@ from SharixAdmin.models import SharixUser
 from SharixAdmin.views.context import get_context
 from django.contrib.auth.mixins import UserPassesTestMixin
 from django.contrib.auth.models import Group
+from django.utils.translation import gettext as _
 
 class UserListView(UserPassesTestMixin, SingleTableView):
     table_class = UserInfoTable
@@ -13,7 +14,7 @@ class UserListView(UserPassesTestMixin, SingleTableView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context.update(get_context(self.request, {
-            'title': 'Управление пользователями',
+            'title': _('User Management'),
             'object_list': context['object_list'],
             'groups': Group.objects.all()
         }))

+ 9 - 8
bin/install.bat

@@ -23,9 +23,10 @@ endlocal
 REM Update repositories
 call :update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-tickets.git" "tickets" "master"
 call :update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-backend.git" "metaservicesynced" "metasynced_module"
-call :update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-webadmin.git" "SharixAdmin\templates\SharixAdmin" "webinterface"
 call :update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-config.git" "conf" "master"
-
+call :update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-webapp-design-template.git" "design_template" "unstable"
+call :update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-webservice-running.git" "webservice_running" "unstable"
+call :update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-landing.git" "landing" "landing_module"
 git pull
 
 REM Create a Python virtual environment and activate it
@@ -36,15 +37,15 @@ REM Upgrade pip and install requirements
 pip install --upgrade pip
 pip install -r requirements.txt
 
-REM Checking for core/config.py
-if exist core\config.py (
-    echo File config.py already created
+REM Checking for core/settings_vars.py
+if exist core\settings_vars.py (
+    echo File settings_vars.py already exists
 ) else (
-    copy core\_config.py core\config.py
-    echo File config.py was successfully created
+    copy core\_settings_vars.py core\settings_vars.py
+    echo File settings_vars.py was successfully created
 )
 
 REM Run Django migrations and other commands
-python manage.py makemigrations SharixAdmin metaservicesynced tickets
+python manage.py makemigrations SharixAdmin metaservicesynced tickets webservice_running landing
 python manage.py migrate
 python manage.py collectstatic --clear --no-input

+ 10 - 9
bin/install.sh

@@ -22,9 +22,10 @@ update_repository() {
 # Update repositories
 update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-tickets.git" "tickets" "master"
 update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-backend.git" "metaservicesynced" "metasynced_module"
-update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-webadmin.git" "SharixAdmin/templates/SharixAdmin" "webinterface"
-update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-config.git" "conf" "master"
-
+update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-settings.git" "conf" "master"
+update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-webapp-design-template.git" "design_template" "unstable"
+update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-webservice-running.git" "webservice_running" "unstable"
+update_repository "https://git.sharix-app.org/ShariX_Open/sharix-open-landing.git" "landing" "landing_module"
 git pull
 
 # Create a Python virtual environment and activate it
@@ -35,16 +36,16 @@ source venv/bin/activate
 pip install --upgrade pip
 pip install -r requirements.txt
 
-# Checking for core/config.py
-if [ -f core/config.py ]; then
-    echo "File config.py already created"
+# Checking for core/settings_vars.py
+if [ -f core/settings_vars.py ]; then
+    echo "File settings_vars.py already exists"
 else
-    cp core/_config.py core/config.py
-    echo "File config.py was successfully created"
+    cp core/_settings_vars.py core/settings_vars.py
+    echo "File settings_vars.py was successfully created"
 fi
 
 # Run Django migrations and other commands
-python manage.py makemigrations SharixAdmin metaservicesynced tickets
+python manage.py makemigrations SharixAdmin metaservicesynced tickets webservice_running landing
 python manage.py migrate
 python manage.py collectstatic -l --no-input
 

+ 0 - 372
core/_config.py

@@ -1,372 +0,0 @@
-import os
-
-from pathlib import Path
-
-from django.contrib.messages import constants as message_constants
-
-
-class ConfigDjango:
-    # Build paths inside the project like this: BASE_DIR / 'subdir'.
-    BASE_DIR = Path(__file__).resolve().parent.parent
-
-    # SECURITY WARNING: keep the secret key used in production secret!
-    SECRET_KEY = 'django-insecure-$eodx2ilnb*djkahfguiwegbwelgbnajl*u$qkt7j-b)7t1iq'
-    # SECURITY WARNING: don't run with debug turned on in production!
-    DEBUG = True
-    CSRF_TRUSTED_ORIGINS = []
-    ALLOWED_HOSTS = ["127.0.0.1"]
-    INTERNAL_IPS = ["127.0.0.1"]
-
-    # Application definition
-    INSTALLED_APPS = [
-        'jazzmin',
-        'django.contrib.admin',
-        'django.contrib.auth',
-        'django.contrib.contenttypes',
-        'django.contrib.sessions',
-        'django.contrib.messages',
-        'django.contrib.staticfiles',
-        'SharixAdmin.apps.SharixadminConfig',
-        'tickets.apps.TicketsConfig',
-        'metaservicesynced.apps.MetaservicesyncedConfig',
-        'django_tables2',
-        "django.contrib.sites",
-        "django.contrib.flatpages",
-        "django.contrib.admindocs",
-        "django_extensions",
-        'rest_framework',
-        'rest_framework.authtoken',
-        'djoser',
-        'schema_graph',
-        'drf_yasg',
-        'django_spaghetti',
-        'debug_toolbar',
-    ]
-
-    MIDDLEWARE = [
-        'django.middleware.security.SecurityMiddleware',
-        'django.contrib.sessions.middleware.SessionMiddleware',
-        'django.middleware.common.CommonMiddleware',
-        'django.middleware.csrf.CsrfViewMiddleware',
-        'django.contrib.auth.middleware.AuthenticationMiddleware',
-        'django.contrib.messages.middleware.MessageMiddleware',
-        'django.middleware.clickjacking.XFrameOptionsMiddleware',
-        'django.contrib.admindocs.middleware.XViewMiddleware',        
-        "debug_toolbar.middleware.DebugToolbarMiddleware",
-    ]
-
-    ROOT_URLCONF = "core.urls"
-
-    SESSION_EXPIRE_AT_BROWSER_CLOSE = False
-    SESSION_SECURITY_WARN_AFTER = 5
-    SESSION_SECURITY_EXPIRE_AFTER = 12
-
-    TEMPLATES = [
-        {
-            "BACKEND": "django.template.backends.django.DjangoTemplates",
-            "DIRS": [os.path.join(BASE_DIR, "templates")],
-            "APP_DIRS": True,
-            "OPTIONS": {
-                "context_processors": [
-                    "django.template.context_processors.debug",
-                    "django.template.context_processors.request",
-                    "django.contrib.auth.context_processors.auth",
-                    "django.template.context_processors.i18n",
-                    "django.template.context_processors.media",
-                    "django.template.context_processors.static",
-                    "django.template.context_processors.tz",
-                    "django.contrib.messages.context_processors.messages",
-                ],
-            },
-        }
-    ]
-
-    WSGI_APPLICATION = 'core.wsgi.application'
-
-    # Database
-    # https://docs.djangoproject.com/en/4.0/ref/settings/#databases
-    DATABASES = {
-        'default': {
-            'ENGINE': 'django.db.backends.sqlite3',
-            'NAME': BASE_DIR / 'db.sqlite3',
-        }
-    }
-
-    # Password validation
-    # https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
-    AUTH_PASSWORD_VALIDATORS = [
-        {
-            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
-        },
-        {
-            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
-        },
-        {
-            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
-        },
-        {
-            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
-        },
-    ]
-
-    # Internationalization
-    # https://docs.djangoproject.com/en/4.0/topics/i18n/
-    LANGUAGE_CODE = 'ru'
-    USE_TZ = True
-    TIME_ZONE = 'Europe/Moscow'
-    SITE_ID = 1
-
-    # If you set this to False, Django will make some optimizations so as not
-    # to load the internationalization machinery.
-    USE_I18N = True
-
-    # Static files (CSS, JavaScript, Images)
-    # https://docs.djangoproject.com/en/4.0/howto/static-files/
-    STATIC_URL = "/static/"
-    STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
-
-    # Uploaded media
-    MEDIA_URL = "/media/"
-    MEDIA_ROOT = os.path.join(BASE_DIR, "media")
-
-    # Without this, uploaded files > 4MB end up with perm 0600, unreadable by web server process
-    FILE_UPLOAD_PERMISSIONS = 0o644
-
-    # Override CSS class for the ERROR tag level to match Bootstrap class name
-    MESSAGE_TAGS = {message_constants.ERROR: "danger"}
-
-    # Default primary key field type
-    # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
-    DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
-
-    AUTH_USER_MODEL = 'SharixAdmin.SharixUser'
-
-
-class ConfigJazzmin:
-    JAZZMIN_SETTINGS = {
-        # title of the window (Will default to current_admin_site.site_title if absent or None)
-        "site_title": "ShariX Admin",
-
-        # Title on the login screen (19 chars max) (defaults to current_admin_site.site_header if absent or None)
-        "site_header": "ShariX Platform",
-
-        # Title on the brand (19 chars max) (defaults to current_admin_site.site_header if absent or None)
-        "site_brand": "ShariX Platform",
-
-        # Logo to use for your site, must be present in static files, used for brand on top left
-        "site_logo": "SharixAdmin/img/logo.svg",
-
-        # Logo to use for your site, must be present in static files, used for login form logo (defaults to site_logo)
-        "login_logo": None,
-
-        # Logo to use for login form in dark themes (defaults to login_logo)
-        "login_logo_dark": None,
-
-        # CSS classes that are applied to the logo above
-        "site_logo_classes": "img-circle",
-
-        # Relative path to a favicon for your site, will default to site_logo if absent (ideally 32x32 px)
-        "site_icon": None,
-
-        # Welcome text on the login screen
-        "welcome_sign": "Welcome to the ShariX Admin",
-
-        # Copyright on the footer
-        "copyright": "Acme Library Ltd",
-
-        # List of model admins to search from the search bar, search bar omitted if excluded
-        # If you want to use a single search field you dont need to use a list, you can use a simple string 
-        "search_model": ["SharixAdmin.SharixUser"],
-
-        # Field name on user model that contains avatar ImageField/URLField/Charfield or a callable that receives the user
-        "user_avatar": "",
-
-        ############
-        # Top Menu #
-        ############
-
-        # Links to put along the top menu
-        "topmenu_links": [
-
-            # Url that gets reversed (Permissions can be added)
-            {"name": "Главная",  "url": "admin:index", "permissions": ["auth.view_user"]},
-
-            # external url that opens in a new window (Permissions can be added)
-            #{"name": "Support", "url": "https://github.com/farridav/django-jazzmin/issues", "new_window": True},
-
-            # model admin to link to (Permissions checked against model)
-            {"model": "SharixAdmin.SharixUser"},
-
-            # App with dropdown menu to all its models pages (Permissions checked against models)
-            {"app": "tickets"},
-        ],
-
-        #############
-        # User Menu #
-        #############
-
-        # Additional links to include in the user menu on the top right ("app" url type is not allowed)
-        # "usermenu_links": [
-        #     {"name": "Support", "url": "https://github.com/farridav/django-jazzmin/issues", "new_window": True},
-        #     {"model": "SharixAdmin.SharixUser"}
-        # ],
-
-        # #############
-        # # Side Menu #
-        # #############
-
-        # # Whether to display the side menu
-        # "show_sidebar": True,
-
-        # # Whether to aut expand the menu
-        # "navigation_expanded": True,
-
-        # # Hide these apps when generating side menu e.g (auth)
-        # "hide_apps": [],
-
-        # # Hide these models when generating side menu (e.g auth.user)
-        # "hide_models": [],
-
-        # # List of apps (and/or models) to base side menu ordering off of (does not need to contain all apps/models)
-        # #"order_with_respect_to": ["auth", "books", "books.author", "books.book"],
-
-        # # Custom links to append to app groups, keyed on app name
-        # "custom_links": {
-        #     "tickets": [{
-        #         "name": "Make Messages", 
-        #         "url": "make_messages", 
-        #         "icon": "fas fa-comments",
-        #         "permissions": ["tickets.view_book"]
-        #     }]
-        # },
-
-        # # Custom icons for side menu apps/models See https://fontawesome.com/icons?d=gallery&m=free&v=5.0.0,5.0.1,5.0.10,5.0.11,5.0.12,5.0.13,5.0.2,5.0.3,5.0.4,5.0.5,5.0.6,5.0.7,5.0.8,5.0.9,5.1.0,5.1.1,5.2.0,5.3.0,5.3.1,5.4.0,5.4.1,5.4.2,5.13.0,5.12.0,5.11.2,5.11.1,5.10.0,5.9.0,5.8.2,5.8.1,5.7.2,5.7.1,5.7.0,5.6.3,5.5.0,5.4.2
-        # # for the full list of 5.13.0 free icon classes
-        "icons": {
-            "auth": "fas fa-users-cog",
-            "auth.user": "fas fa-user",
-            "auth.Group": "fas fa-users",
-            "SharixAdmin": "fas fa-users-cog",
-            "SharixAdmin.SharixUser": "fas fa-user",
-            "tickets.Task": "fas fa-check",
-            "tickets.TaskList": "fas fa-list",
-            "tickets.Comment": "fas fa-comment",
-            "tickets.Attachment": "fas fa-file",
-        },
-        # # Icons that are used when one is not manually specified
-        # # "default_icon_parents": "fas fa-chevron-circle-right",
-        # # "default_icon_children": "fas fa-circle",
-
-        # #################
-        # # Related Modal #
-        # #################
-        # # Use modals instead of popups
-        # "related_modal_active": False,
-
-        # #############
-        # # UI Tweaks #
-        # #############
-        # # Relative paths to custom CSS/JS scripts (must be present in static files)
-        "custom_css": None,
-        "custom_js": None,
-        # Whether to link font from fonts.googleapis.com (use custom_css to supply font otherwise)
-        "use_google_fonts_cdn": True,
-        # # Whether to show the UI customizer on the sidebar
-        "show_ui_builder": True,
-
-        ###############
-        # Change view #
-        ###############
-        # Render out the change view as a single form, or in tabs, current options are
-        # - single
-        # - horizontal_tabs (default)
-        # - vertical_tabs
-        # - collapsible
-        # - carousel
-        #"changeform_format": "horizontal_tabs",
-        # override change forms on a per modeladmin basis
-        #"changeform_format_overrides": {"SharixAdmin.SharixUser": "collapsible", "auth.group": "vertical_tabs"},
-        # Add a language dropdown into the admin
-        #"language_chooser": True,
-    }
-    JAZZMIN_UI_TWEAKS = {
-        "navbar_small_text": True,
-        "footer_small_text": True,
-        "body_small_text": False,
-        "brand_small_text": True,
-        "brand_colour": "navbar-light",
-        "accent": "accent-navy",
-        "navbar": "navbar-navy navbar-dark",
-        "no_navbar_border": False,
-        "navbar_fixed": False,
-        "layout_boxed": False,
-        "footer_fixed": False,
-        "sidebar_fixed": True,
-        "sidebar": "sidebar-light-navy",
-        "sidebar_nav_small_text": False,
-        "sidebar_disable_expand": False,
-        "sidebar_nav_child_indent": False,
-        "sidebar_nav_compact_style": True,
-        "sidebar_nav_legacy_style": False,
-        "sidebar_nav_flat_style": False,
-        "theme": "default",
-        "dark_mode_theme": None,
-        "button_classes": {
-            "primary": "btn-outline-primary",
-            "secondary": "btn-outline-secondary",
-            "info": "btn-outline-info",
-            "warning": "btn-outline-warning",
-            "danger": "btn-outline-danger",
-            "success": "btn-outline-success"
-        },
-        "actions_sticky_top": False
-    }
-
-
-class ConfigAPI:
-    REST_FRAMEWORK = {
-        # Use Django's standard `django.contrib.auth` permissions,
-        # or allow read-only access for unauthenticated users.
-        'DEFAULT_RENDERER_CLASSES':[
-            'rest_framework.renderers.JSONRenderer',
-            'rest_framework.renderers.BrowsableAPIRenderer',
-        ],
-        'DEFAULT_PERMISSION_CLASSES': [
-            #'rest_framework.permissions.AllowAny',
-            #'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
-        ],
-        'DEFAULT_AUTHENTICATION_CLASSES': (
-            'rest_framework.authentication.TokenAuthentication',
-            'rest_framework.authentication.BasicAuthentication',
-            'rest_framework.authentication.SessionAuthentication',
-        ),
-    }
-
-    SPAGHETTI_SAUCE = {
-        'apps': ['auth', 'SharixAdmin', 
-                'tickets', 'admin', 
-                'flatpages', 'sessions', 'sites', 'metaservicesynced'],
-        'show_fields': False,
-        'show_proxy':True,
-    }
-
-    GRAPH_MODELS = {
-        'all_applications': True,
-        'group_models': True,
-    }
-
-    DJOSER = {
-        'SERIALIZERS': {
-            'token': 'SharixAdmin.api.serializers.CustomTokenSerializer',
-        }
-    }
-
-
-class ConfigGunicorn:
-    bind = "127.0.0.1:8000"
-    workers = 2
-    worker_class = "sync"
-    threads = 4
-    timeout = 30
-    max_requests = 1000
-    capture_output = True

+ 49 - 0
core/_settings_vars.py

@@ -0,0 +1,49 @@
+########
+#
+# Django
+#
+########
+
+DEBUG = True
+SECRET_KEY = 'django-insecure-$eodx2ilnb*djkahfguiwegbwelgbnajl*u$qkt7j-b)7t1iq'
+CSRF_TRUSTED_ORIGINS = []
+ALLOWED_HOSTS = ["127.0.0.1"]
+INTERNAL_IPS = ["127.0.0.1"]
+NAME_SYSTEM = "ShariX"
+API_URL = 'http://127.0.0.1:8000'
+
+########
+#
+# Database
+#
+########
+
+DB_NAME = None
+DB_USER = None
+DB_PASSWORD = None
+DB_HOST = None
+DB_PORT = 5432
+
+########
+#
+# Gunicorn
+#
+########
+
+BIND = "127.0.0.1:8000"
+
+########
+#
+# ejabber
+#
+########
+
+EJ_PROTOCOL = "http"
+EJ_IP = "10.0.20.9"
+EJ_PORT = "5280"
+EJ_URL = EJ_PROTOCOL + "://" + EJ_IP + ":" + EJ_PORT + "/" + "api/"
+EJ_SERVICE = "chat.ej.sharix-app.org"
+EJ_HOST = "ej.sharix-app.org"
+
+# Service name that is used in generating ejabber rooms
+WEBSERVICE_NAME = "open" 

+ 8 - 3
core/gunicorn.py

@@ -1,5 +1,10 @@
-from core.utils import setup
-from core.config import ConfigGunicorn
+import core.settings_vars as sv
 
 
-setup(locals(), ConfigGunicorn)
+bind = sv.BIND
+workers = 2
+worker_class = "sync"
+threads = 4
+timeout = 30
+max_requests = 1000
+capture_output = True

+ 400 - 5
core/settings.py

@@ -1,7 +1,402 @@
-from core.utils import setup
-from core.config import ConfigDjango, ConfigJazzmin, ConfigAPI
+import os
 
+from pathlib import Path
 
-setup(locals(), ConfigDjango)
-setup(locals(), ConfigJazzmin)
-setup(locals(), ConfigAPI)
+from django.contrib.messages import constants as message_constants
+from django.utils.translation import gettext_lazy as _
+
+import core.settings_vars as sv
+
+
+########
+#
+# Django
+#
+########
+
+# Build paths inside the project like this: BASE_DIR / 'subdir'.
+BASE_DIR = Path(__file__).resolve().parent.parent
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = sv.SECRET_KEY
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = sv.DEBUG
+CSRF_TRUSTED_ORIGINS = sv.CSRF_TRUSTED_ORIGINS
+ALLOWED_HOSTS = sv.ALLOWED_HOSTS 
+INTERNAL_IPS = sv.INTERNAL_IPS
+
+# Application definition
+INSTALLED_APPS = [
+    'design_template',
+    'jazzmin',
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'SharixAdmin.apps.SharixadminConfig',
+    'tickets.apps.TicketsConfig',
+    'metaservicesynced.apps.MetaservicesyncedConfig',
+    'webservice_running.apps.WebserviceRunningConfig',
+    'django_tables2',
+    "django.contrib.sites",
+    "django.contrib.flatpages",
+    "django.contrib.admindocs",
+    "django_extensions",
+    'rest_framework',
+    'rest_framework.authtoken',
+    'djoser',
+    'schema_graph',
+    'drf_yasg',
+    'django_spaghetti',
+    'debug_toolbar',
+    'ckeditor',
+    'landing.apps.LandingConfig',
+]
+
+MIDDLEWARE = [
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.locale.LocaleMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    'django.contrib.admindocs.middleware.XViewMiddleware',        
+    "debug_toolbar.middleware.DebugToolbarMiddleware",
+]
+
+ROOT_URLCONF = "core.urls"
+
+SESSION_EXPIRE_AT_BROWSER_CLOSE = False
+SESSION_SECURITY_WARN_AFTER = 5
+SESSION_SECURITY_EXPIRE_AFTER = 12
+
+TEMPLATES = [
+    {
+        "BACKEND": "django.template.backends.django.DjangoTemplates",
+        "DIRS": [os.path.join(BASE_DIR, "templates")],
+        "APP_DIRS": True,
+        "OPTIONS": {
+            "context_processors": [
+                "django.template.context_processors.debug",
+                "django.template.context_processors.request",
+                "django.contrib.auth.context_processors.auth",
+                "django.template.context_processors.i18n",
+                "django.template.context_processors.media",
+                "django.template.context_processors.static",
+                "django.template.context_processors.tz",
+                "design_template.context_processors.get_name_system",
+                "django.contrib.messages.context_processors.messages",
+            ],
+        },
+    }
+]
+
+WSGI_APPLICATION = 'core.wsgi.application'
+
+# Database
+# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
+if sv.DB_NAME:
+    DATABASES = {
+        'default': {
+            'ENGINE': 'django.db.backends.postgresql',
+            'NAME': sv.DB_NAME,
+            'USER': sv.DB_USER,
+            'PASSWORD': sv.DB_PASSWORD,
+            'HOST': sv.DB_HOST,
+            'PORT': sv.DB_PORT,
+        }
+    }
+else:
+    DATABASES = {
+        'default': {
+            'ENGINE': 'django.db.backends.sqlite3',
+            'NAME': BASE_DIR / 'db.sqlite3',
+        }
+    }
+    
+
+# Password validation
+# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+    },
+    {
+        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+    },
+]
+
+# Internationalization
+# https://docs.djangoproject.com/en/4.0/topics/i18n/
+LANGUAGE_CODE = 'ru'
+USE_TZ = True
+TIME_ZONE = 'Europe/Moscow'
+SITE_ID = 1
+
+# If you set this to False, Django will make some optimizations so as not
+# to load the internationalization machinery.
+USE_I18N = True
+
+LANGUAGES = [
+    ('ru', _('Russian')),
+    ('en', _('English')),
+]
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/4.0/howto/static-files/
+STATIC_URL = "/static/"
+STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
+
+# Uploaded media
+MEDIA_URL = "/media/"
+MEDIA_ROOT = os.path.join(BASE_DIR, "media")
+
+# Without this, uploaded files > 4MB end up with perm 0600, unreadable by web server process
+FILE_UPLOAD_PERMISSIONS = 0o644
+
+# Override CSS class for the ERROR tag level to match Bootstrap class name
+MESSAGE_TAGS = {message_constants.ERROR: "danger"}
+
+# Default primary key field type
+# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
+DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
+
+AUTH_USER_MODEL = 'SharixAdmin.SharixUser'
+
+NAME_SYSTEM = sv.NAME_SYSTEM
+
+########
+#
+# Jazzmin
+#
+########
+
+JAZZMIN_SETTINGS = {
+    # title of the window (Will default to current_admin_site.site_title if absent or None)
+    "site_title": "ShariX Admin",
+
+    # Title on the login screen (19 chars max) (defaults to current_admin_site.site_header if absent or None)
+    "site_header": "ShariX Platform",
+
+    # Title on the brand (19 chars max) (defaults to current_admin_site.site_header if absent or None)
+    "site_brand": "ShariX Platform",
+
+    # Logo to use for your site, must be present in static files, used for brand on top left
+    "site_logo": "SharixAdmin/img/logo.png",
+
+    # Logo to use for your site, must be present in static files, used for login form logo (defaults to site_logo)
+    "login_logo": None,
+
+    # Logo to use for login form in dark themes (defaults to login_logo)
+    "login_logo_dark": None,
+
+    # CSS classes that are applied to the logo above
+    "site_logo_classes": "img-circle",
+
+    # Relative path to a favicon for your site, will default to site_logo if absent (ideally 32x32 px)
+    "site_icon": None,
+
+    # Welcome text on the login screen
+    "welcome_sign": "Welcome to the ShariX Admin",
+
+    # Copyright on the footer
+    "copyright": "Acme Library Ltd",
+
+    # List of model admins to search from the search bar, search bar omitted if excluded
+    # If you want to use a single search field you dont need to use a list, you can use a simple string 
+    "search_model": ["SharixAdmin.SharixUser"],
+
+    # Field name on user model that contains avatar ImageField/URLField/Charfield or a callable that receives the user
+    "user_avatar": "",
+
+    ############
+    # Top Menu #
+    ############
+
+    # Links to put along the top menu
+    "topmenu_links": [
+
+        # Url that gets reversed (Permissions can be added)
+        {"name": "Главная",  "url": "admin:index", "permissions": ["auth.view_user"]},
+
+        # external url that opens in a new window (Permissions can be added)
+        #{"name": "Support", "url": "https://github.com/farridav/django-jazzmin/issues", "new_window": True},
+
+        # model admin to link to (Permissions checked against model)
+        {"model": "SharixAdmin.SharixUser"},
+
+        # App with dropdown menu to all its models pages (Permissions checked against models)
+        {"app": "tickets"},
+    ],
+
+    #############
+    # User Menu #
+    #############
+
+    # Additional links to include in the user menu on the top right ("app" url type is not allowed)
+    # "usermenu_links": [
+    #     {"name": "Support", "url": "https://github.com/farridav/django-jazzmin/issues", "new_window": True},
+    #     {"model": "SharixAdmin.SharixUser"}
+    # ],
+
+    # #############
+    # # Side Menu #
+    # #############
+
+    # # Whether to display the side menu
+    # "show_sidebar": True,
+
+    # # Whether to aut expand the menu
+    # "navigation_expanded": True,
+
+    # # Hide these apps when generating side menu e.g (auth)
+    # "hide_apps": [],
+
+    # # Hide these models when generating side menu (e.g auth.user)
+    # "hide_models": [],
+
+    # # List of apps (and/or models) to base side menu ordering off of (does not need to contain all apps/models)
+    # #"order_with_respect_to": ["auth", "books", "books.author", "books.book"],
+
+    # # Custom links to append to app groups, keyed on app name
+    # "custom_links": {
+    #     "tickets": [{
+    #         "name": "Make Messages", 
+    #         "url": "make_messages", 
+    #         "icon": "fas fa-comments",
+    #         "permissions": ["tickets.view_book"]
+    #     }]
+    # },
+
+    # # Custom icons for side menu apps/models See https://fontawesome.com/icons?d=gallery&m=free&v=5.0.0,5.0.1,5.0.10,5.0.11,5.0.12,5.0.13,5.0.2,5.0.3,5.0.4,5.0.5,5.0.6,5.0.7,5.0.8,5.0.9,5.1.0,5.1.1,5.2.0,5.3.0,5.3.1,5.4.0,5.4.1,5.4.2,5.13.0,5.12.0,5.11.2,5.11.1,5.10.0,5.9.0,5.8.2,5.8.1,5.7.2,5.7.1,5.7.0,5.6.3,5.5.0,5.4.2
+    # # for the full list of 5.13.0 free icon classes
+    "icons": {
+        "auth": "fas fa-users-cog",
+        "auth.user": "fas fa-user",
+        "auth.Group": "fas fa-users",
+        "SharixAdmin": "fas fa-users-cog",
+        "SharixAdmin.SharixUser": "fas fa-user",
+        "tickets.Task": "fas fa-check",
+        "tickets.TaskList": "fas fa-list",
+        "tickets.Comment": "fas fa-comment",
+        "tickets.Attachment": "fas fa-file",
+    },
+    # # Icons that are used when one is not manually specified
+    # # "default_icon_parents": "fas fa-chevron-circle-right",
+    # # "default_icon_children": "fas fa-circle",
+
+    # #################
+    # # Related Modal #
+    # #################
+    # # Use modals instead of popups
+    # "related_modal_active": False,
+
+    # #############
+    # # UI Tweaks #
+    # #############
+    # # Relative paths to custom CSS/JS scripts (must be present in static files)
+        "custom_css": None,
+        "custom_js": None,
+    # Whether to link font from fonts.googleapis.com (use custom_css to supply font otherwise)
+        "use_google_fonts_cdn": True,
+    # # Whether to show the UI customizer on the sidebar
+    "show_ui_builder": True,
+
+    ###############
+    # Change view #
+    ###############
+    # Render out the change view as a single form, or in tabs, current options are
+    # - single
+    # - horizontal_tabs (default)
+    # - vertical_tabs
+    # - collapsible
+    # - carousel
+    #"changeform_format": "horizontal_tabs",
+    # override change forms on a per modeladmin basis
+    #"changeform_format_overrides": {"SharixAdmin.SharixUser": "collapsible", "auth.group": "vertical_tabs"},
+    # Add a language dropdown into the admin
+    #"language_chooser": True,
+}
+
+JAZZMIN_UI_TWEAKS = {
+    "navbar_small_text": True,
+    "footer_small_text": True,
+    "body_small_text": False,
+    "brand_small_text": True,
+    "brand_colour": "navbar-light",
+    "accent": "accent-navy",
+    "navbar": "navbar-navy navbar-dark",
+    "no_navbar_border": False,
+    "navbar_fixed": False,
+    "layout_boxed": False,
+    "footer_fixed": False,
+    "sidebar_fixed": True,
+    "sidebar": "sidebar-light-navy",
+    "sidebar_nav_small_text": False,
+    "sidebar_disable_expand": False,
+    "sidebar_nav_child_indent": False,
+    "sidebar_nav_compact_style": True,
+    "sidebar_nav_legacy_style": False,
+    "sidebar_nav_flat_style": False,
+    "theme": "default",
+    "dark_mode_theme": None,
+    "button_classes": {
+        "primary": "btn-outline-primary",
+        "secondary": "btn-outline-secondary",
+        "info": "btn-outline-info",
+        "warning": "btn-outline-warning",
+        "danger": "btn-outline-danger",
+        "success": "btn-outline-success"
+    },
+    "actions_sticky_top": False
+}
+
+########
+#
+# API
+#
+########
+
+API_URL = sv.API_URL
+
+REST_FRAMEWORK = {
+    # Use Django's standard `django.contrib.auth` permissions,
+    # or allow read-only access for unauthenticated users.
+    'DEFAULT_RENDERER_CLASSES':[
+        'rest_framework.renderers.JSONRenderer',
+        'rest_framework.renderers.BrowsableAPIRenderer',
+    ],
+    'DEFAULT_PERMISSION_CLASSES': [
+        #'rest_framework.permissions.AllowAny',
+        #'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
+    ],
+    'DEFAULT_AUTHENTICATION_CLASSES': (
+        'rest_framework.authentication.TokenAuthentication',
+        'rest_framework.authentication.BasicAuthentication',
+        'rest_framework.authentication.SessionAuthentication',
+    ),
+}
+
+SPAGHETTI_SAUCE = {
+    'apps': ['auth', 'SharixAdmin', 
+                'tickets', 'admin', 
+                'flatpages', 'sessions', 'sites', 'metaservicesynced'],
+    'show_fields': False,
+    'show_proxy':True,
+}
+
+GRAPH_MODELS = {
+    'all_applications': True,
+    'group_models': True,
+}

+ 12 - 4
core/urls.py

@@ -2,15 +2,23 @@ from django.contrib import admin
 from django.conf import settings
 from django.urls import path, include
 from django.conf.urls.static import static
+from django.conf.urls.i18n import i18n_patterns
 
 
 urlpatterns = [
     path('admin/doc/', include('django.contrib.admindocs.urls')),
     path('admin/', admin.site.urls),
-    path('', include('SharixAdmin.urls')),
-    path('tickets/', include('tickets.urls', namespace='tickets'), name='tickets'),
-    path('metaservicesynced/', include("metaservicesynced.urls"), name="metaservicesynced"),
-] 
+] + i18n_patterns(
+        path('i18n/', include('django.conf.urls.i18n')),
+        path('', include('SharixAdmin.urls')),
+        path('tickets/', include('tickets.urls', namespace='tickets'), name='tickets'),
+        path('design/', include("design_template.urls"), name='design'),
+        path('metaservicesynced/', include("metaservicesynced.urls"), name="metaservicesynced"),
+        path('webservice/', include("webservice_running.urls"), name='webservice_running'),
+        path('landing/', include("landing.urls"), name="landing"),
+        prefix_default_language=False,
+    )
+    
 
 if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

+ 0 - 8
core/utils.py

@@ -1,8 +0,0 @@
-def setup(local_namespace: dict, config_class):
-    """setup(local_namespace: dict, config_class)
-
-    Adds all attributes of the configuration class
-    to the passed namespace as ordinary variables.
-    
-    """
-    local_namespace.update(vars(config_class))

+ 46 - 0
core/utils/AuthAPI.py

@@ -0,0 +1,46 @@
+'''
+That class provides the ability to authenticate an application account through the
+API and store these authentication tokens.
+
+Modules using the API should log in ShariX system using this class.
+'''
+
+import requests
+
+from core.settings import API_URL
+
+
+class AuthAPI:
+    def __init__(self, login: str, password: str):
+        self._login = login
+        self._password = password
+        self._token = None
+        self._headers =  None
+
+    def _create_token(self):
+        try:
+            response = requests.post(
+                f"{API_URL}/auth/token/login/", 
+                {
+                    "phone_number": self._login,
+                    "password": self._password
+                }
+            )
+            self._token = response.json()["auth_token"]
+        except requests.exceptions.ConnectionError:
+            print("\033[31m" + f"{self.__class__.__name__}: Can't connect to the API." + "\033[0m")
+        except KeyError:
+            print("\033[31m" + f"{self.__class__.__name__}: Incorrect login data." + "\033[0m")
+    
+    @property
+    def token(self):
+        if self._token is None:
+            self._create_token()
+        return self._token
+
+    @property
+    def headers(self):
+        if self._token is None:
+            self._create_token()
+            self._headers =  {'Authorization': f'Token {self._token}'}
+        return self._headers

BIN
media/tasks/attachments/1/payment.png


+ 1 - 0
requirements.txt

@@ -56,3 +56,4 @@ uritemplate==4.1.1
 urllib3==1.26.14
 webencodings==0.5.1
 xmpppy==0.7.1
+django-ckeditor

Some files were not shown because too many files changed in this diff