浏览代码

making service tariff pages working more real

ShariX Developer 21 小时之前
父节点
当前提交
96b8255eb7

+ 47 - 9
sharix_admin/forms/service.py

@@ -2,6 +2,15 @@ from dbsynce.models import ServiceCategory, Service, Company
 from django import forms
 from sharix_admin.forms import BaseForm
 
+#RESOURCE_TYPE_CHOICES = [
+#    ('1', 'Только время'),
+#    ('2', 'Только расстояние'),
+#    ('3', 'За единицу услуги'),
+#    ('4', 'Время за расстояние'),
+#    ('5', 'Единицы за расстояние'),
+#    ('6', 'Единицы за время'),
+#]
+
 class ServiceTariffUpdateForm(forms.ModelForm):
     def __init__(self, *args, **kwargs):
         super(ServiceTariffUpdateForm, self).__init__(*args, **kwargs)
@@ -12,15 +21,18 @@ class ServiceTariffUpdateForm(forms.ModelForm):
                 self.fields[field].widget.attrs.update({'class': 'form-control'})
 
     class Meta:
-
         model = Service
         fields = [
-            'status',
-            'ticket_status',
+            #'status',
+            #'ticket_status',
             'service_category',
-            'resource',
             'requirements',
-            'price_type',
+            'company_comission',
+            'codename',
+            'caption',
+            'description',
+            'resource_type',
+#            'price_type',
             'price_km',
             'price_min',
             'price_amount',
@@ -30,13 +42,28 @@ class ServiceTariffUpdateForm(forms.ModelForm):
         widgets = {
             'status': forms.TextInput(attrs={'readonly': True}, ),
             'ticket_status': forms.TextInput(attrs={'readonly': True}),
+            'requirements': forms.TextInput(attrs={'readonly': True}),
+            'resource_type': forms.TextInput(attrs={'readonly': True}),
+#            'price_type': forms.TextInput(attrs={'readonly': True}),
 
-            'service_category': forms.Select(attrs={'class': 'form-select'}),
-            'resource': forms.Select(attrs={'class': 'form-select'}),
+            'service_category': forms.Select(attrs={'class': 'form-select', 'readonly': True}),
+            #'resource': forms.Select(attrs={'class': 'form-select'}),
         }
 
 
 class ServiceTariffCreateForm(forms.ModelForm):
+    company_comission = forms.FloatField(label="Комиссия Партнера")
+    resource_type = forms.CharField(label="Необходимый тип ресурса")
+    #resource_type = forms.ChoiceField(choices=RESOURCE_TYPE_CHOICES, label="Необходимый тип ресурса")
+    codename = forms.CharField(label="Кодовое короткое название тарифа услуги")
+    caption = forms.CharField(label="Название тарифа услуги")
+    #requirements = forms.CharField(label="Требования")
+    #price_type = forms.ChoiceField(choices=PRICE_CHOICES, label="Ценообразование")
+    description = forms.CharField(label="Описание")
+
+#    is_global = forms.BooleanField(label="Доступно во всех сервисах", required=False)
+#    is_visible = forms.BooleanField(label="Доступно для планирования цепочек во всех сервисах", required=False)
+
     def __init__(self, *args, **kwargs):
         super(ServiceTariffCreateForm, self).__init__(*args, **kwargs)
         # Добавляет стиль бутстрапа form-control всем полям таблицы если у них нет своих стилей
@@ -47,11 +74,22 @@ class ServiceTariffCreateForm(forms.ModelForm):
     class Meta:
 
         model = Service
-        fields = '__all__'
+        #fields = '__all__'
+        fields = [
+            'service_category',
+            'company_comission',
+            'codename',
+            'caption',
+            'description',
+            'resource_type',
+        ]
+
+        #company - использовать ту, у которой сейчас отображаются услуги
+        #resource - показывать только те, которые имеют отношение к компании
 
         widgets = {
             'service_category': forms.Select(attrs={'class': 'form-select'}),
-            'resource': forms.Select(attrs={'class': 'form-select'}),
+            #'resource': forms.Select(attrs={'class': 'form-select'}),
             'ticket_status': forms.TextInput(attrs={'readonly': True}),
         }
 

+ 28 - 4
sharix_admin/tables.py

@@ -272,23 +272,43 @@ class ServiceTariffsTable(tables.Table):
             "td": {"width": "5%"}
         }
     )
-    service_category = tables.LinkColumn(
+    codename = tables.LinkColumn(
         'sharix_admin:service_tariff/edit/',
-        verbose_name=_('Name of the tariff'),
+        verbose_name=_('Кодовое название'),
+        text=lambda record: record.caption,
+        args=[tables.A('pk')],
+        attrs={
+            'th': {'scope': 'col'},
+            "td": {"width": "15%"}
+        }
+    )
+    #service_category = tables.Column(
+    service_category = tables.LinkColumn(
+        'sharix_admin:service_category/edit/',
+        verbose_name=_('Название схемы услуги'),
         text=lambda record: record.service_category.caption,
         args=[tables.A('pk')],
+        attrs={
+            'th': {'scope': 'col'},
+            "td": {"width": "15%"}
+        }
+    )
+    resource_type = tables.Column(
+        verbose_name=_('Тип ресурса'),
         attrs={
             'th': {'scope': 'col'},
             "td": {"width": "20%"}
         }
     )
-    ticket_status = tables.Column(
-        verbose_name=_('Name of the service scheme'),
+
+    company_comission = tables.Column(
+        verbose_name=_('Комиссия партнера'),
         attrs={
             'th': {'scope': 'col'},
             "td": {"width": "20%"}
         }
     )
+
     check = tables.BooleanColumn(
         verbose_name=_('Activity'),
         orderable=False,
@@ -305,11 +325,15 @@ class ServiceTariffsTable(tables.Table):
         }
         exclude = (
             'resource',
+            'company',
+            'caption',
+            'description',
             'price_type',
             'price_min',
             'price_amount',
             'id_metaservice',
             'requirements',
+            'ticket_status',
             'price_km',
             'is_global',
             'is_visible',

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

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

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

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

+ 1 - 1
sharix_admin/urls.py

@@ -66,6 +66,7 @@ urlpatterns = [
     path('provider/change_status/', change_provider_status, name='provider/change_status'),
 
     path('service_tariffs/', login_required(ServiceTariffsListView.as_view()), name='service_tariffs'),
+    path('service_tariffs/my/', login_required(ServiceTariffsMyListView.as_view()), name='service_tariffs/my'),
     # path('service_tariff/<int:pk>', login_required(ServiceTariffDetailView.as_view()), name='service_tariff_detail'),
 
     path('service_tariff/add/', login_required(ServiceTariffCreate.as_view()), name='service_tariff/add/'),
@@ -77,7 +78,6 @@ urlpatterns = [
     #path('service_category/<int:pk>', login_required(ServiceCategoryDetailView.as_view()), name='service_category'),
     path('service_category/edit/<int:pk>', login_required(ServiceCategoryUpdateView.as_view()), name='service_category/edit/'),
     path('service_category/add/', login_required(ServiceCategoryCreate.as_view()), name='service_category/add/'),
-#    path('service_category/delete/<int:pk>', login_required(ServiceCategoryDelete.as_view()), name='service_category/delete/'),
     path('service_category/change_status/', change_service_category_status, name='service_category/change_status'),
 
 #CHECK Maybe obsolete

+ 195 - 5
sharix_admin/views/service.py

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

+ 3 - 3
sharix_admin/views/service_tariff.py

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