Browse Source

Incomplete functionality of partner document upload

TonyKurts 3 months ago
parent
commit
e65e38c552

+ 2 - 1
SharixAdmin/forms/__init__.py

@@ -1,3 +1,4 @@
 from .login import LoginUserForm
 from .login import LoginUserForm
 from .service import *
 from .service import *
-from .company import *
+from .company import *
+from .document import *

+ 44 - 0
SharixAdmin/forms/document.py

@@ -0,0 +1,44 @@
+import datetime
+
+from django import forms
+from django.core.exceptions import ValidationError
+
+
+class DocumentUploadForm(forms.Form):
+    doc_expire_date = forms.DateField(
+        required=False,
+        widget=forms.DateInput(attrs={
+            'class': 'form-control',
+            'type': 'date',
+        }),
+        label='Дата окончания действия документа (при наличии)'
+    )
+    doc_file = forms.FileField(
+        widget=forms.ClearableFileInput(attrs={'multiple': True}),
+        required=True,
+    )
+
+    # Дата истечения срока документа не может быть в прошлом
+    def clean_doc_expire_date(self):
+        doc_expire_date = self.cleaned_data.get('doc_expire_date')
+        if doc_expire_date and doc_expire_date < datetime.date.today():
+            raise ValidationError("Дата окончания действия документа не может быть в прошлом.")
+        return doc_expire_date
+
+    # Загружаемые файлы должны иметь только допустимый тип и расширение
+    def clean_doc_file(self):
+        files = self.files.getlist('doc_file')
+        allowed_mime_types = ['image/jpeg', 'image/png', 'application/pdf']
+        allowed_extensions = ['jpg', 'jpeg', 'png', 'pdf']
+        
+        for file in files:
+            # Проверяем расширение файла
+            extension = file.name.split('.')[-1].lower()
+            if extension not in allowed_extensions:
+                raise ValidationError(f"Файл {file.name} имеет недопустимое расширение. Допустимые расширения: {', '.join(allowed_extensions)}.")
+
+            # Проверяем MIME тип файла
+            if file.content_type not in allowed_mime_types:
+                raise ValidationError(f"Файл {file.name} имеет недопустимый формат. Допустимые форматы: {', '.join(allowed_mime_types)}.")
+        
+        return files

+ 1 - 0
SharixAdmin/static/SharixAdmin/css/style.css

@@ -128,6 +128,7 @@
     align-items: center;
     align-items: center;
     height: 256px;
     height: 256px;
     padding: 2em;
     padding: 2em;
+    width: 100%;
     border-radius: 10px;
     border-radius: 10px;
     border: 2px dashed #55555597;
     border: 2px dashed #55555597;
     color: #444;
     color: #444;

+ 1 - 1
SharixAdmin/templates/SharixAdmin/include/form.html

@@ -6,7 +6,7 @@
             <small class="form-text text-muted">{{ field.help_text }}</small>
             <small class="form-text text-muted">{{ field.help_text }}</small>
         {% endif %}
         {% endif %}
         {% if field.errors %}
         {% if field.errors %}
-            <ul class="errorlist">
+            <ul class="alert alert-danger list-style-none">
                 {% for error in field.errors %}
                 {% for error in field.errors %}
                     <li>{{ error }}</li>
                     <li>{{ error }}</li>
                 {% endfor %}
                 {% endfor %}

+ 14 - 4
SharixAdmin/templates/SharixAdmin/partner.html

@@ -34,14 +34,24 @@
 
 
 <h6 class="mb-4">Документы</h6>
 <h6 class="mb-4">Документы</h6>
     <ul class="list-style-none">
     <ul class="list-style-none">
-        {% for doc_code in doc_codes %}
+        {% for doc in docs %}
             <li class="d-flex justify-content-between">
             <li class="d-flex justify-content-between">
                 <div class="d-flex align-items-center">
                 <div class="d-flex align-items-center">
                     <img class="me-2 no-user-select" style="height: 32px;" src="{% static "SharixAdmin/img/file.svg" %}">
                     <img class="me-2 no-user-select" style="height: 32px;" src="{% static "SharixAdmin/img/file.svg" %}">
-                    {{ doc_dict|get_item:doc_code }}
+                    {{ doc.get_doc_type_display }}
+                    
+                    {% if doc.files.all %}
+                        <span class="me-3 text-secondary ms-1">
+                            (на проверке)
+                        </span>
+                    {% endif %}
                 </div>
                 </div>
-                  
-                <a class="btn btn-sm btn-outline-primary" href="{% url "partner_doc" doc_code %}">Загрузить</a>
+                
+                {% if not doc.files.all %}
+                    <a class="btn btn-sm btn-primary" href="{% url "partner_doc_edit" doc.doc_type %}">Загрузить</a>
+                {% else %}
+                    <a class="btn btn-sm btn-outline-primary" href="{% url "partner_doc_edit" doc.doc_type %}">Изменить</a>
+                {% endif %}
             </li>
             </li>
         {% endfor %}
         {% endfor %}
     </ul>
     </ul>

+ 48 - 7
SharixAdmin/templates/SharixAdmin/partner_doc.html

@@ -10,15 +10,56 @@
     Это система управления государством, источником власти в которой является сам народ. Именно народ решает, какие законы и нормы необходимы для гармоничного существования и развития государства.
     Это система управления государством, источником власти в которой является сам народ. Именно народ решает, какие законы и нормы необходимы для гармоничного существования и развития государства.
 </p>
 </p>
 
 
-<form>
+<form class="d-flex flex-column align-items-end" enctype="multipart/form-data" method="POST">
     {% csrf_token %}
     {% csrf_token %}
-    <label for="doc-expire-date" class="form-label">Дата окончания действия документа (при наличии)</label>
-    <input id="doc-expire-date" type="date" name="doc_expire_date" class="form-control">
+    <div class="w-100">
+        <label for="{{ form.doc_expire_date.id_for_label }}" class="form-label">{{ form.doc_expire_date.label }}</label>
+        {{ form.doc_expire_date }}
+        
+        {% if form.doc_expire_date.errors %}
+            <ul class="alert alert-danger list-style-none mt-2 p-2">
+                {% for error in form.doc_expire_date.errors %}
+                    <li>{{ error }}</li>
+                {% endfor %}
+            </ul>
+        {% endif %}
+    </div>
+
+    <div class="my-3 w-100">
+        <div class="drop-container">
+            <span class="drop-title">Перетащите файлы сюда</span>
+            или выберите их на своем устройстве (только PDF, PNG, JPG, JPEG)
+            {{ form.doc_file }}
+        </div>
+
+        {% if form.doc_file.errors %}
+            <ul class="alert alert-danger list-style-none mt-2 p-2">
+                {% for error in form.doc_file.errors %}
+                    <li>{{ error }}</li>
+                {% endfor %}
+            </ul>
+        {% endif %}
+    </div>
+    
+    <button class="btn btn-primary" type="button" data-bs-toggle="modal" data-bs-target="#partner-doc-modal">Отправить</button>
 
 
-    <div class="drop-container mt-3">
-        <span class="drop-title">Перетащите файлы сюда</span>
-        или выберите их на своем устройстве
-        <input id="doc_file" type="file" multiple="multiple" name="doc_file" required>
+    <!-- Окно подтверждения -->
+    <div id="partner-doc-modal" class="modal fade" tabindex="-1">
+        <div class="modal-dialog modal-dialog-centered">
+          <div class="modal-content">
+            <div class="modal-header">
+              <h5 class="modal-title">Подтверждение действия</h5>
+              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+            </div>
+            <div class="modal-body">
+              <p>Внесение изменений приведет к деактивации партнера до момента проверки новой информации!</p>
+            </div>
+            <div class="modal-footer">
+              <button type="button" class="btn btn-primary" data-bs-dismiss="modal">Отменить</button>
+              <button type="sumbit" class="btn btn-outline-primary">Подтвердить</button>
+            </div>
+          </div>
+        </div>
     </div>
     </div>
 </form>
 </form>
 {% endblock contenthome %}
 {% endblock contenthome %}

+ 0 - 6
SharixAdmin/templatetags.py

@@ -1,6 +0,0 @@
-from django.template.defaulttags import register
-
-
-@register.filter
-def get_item(dictionary, key):
-    return dictionary.get(key)

+ 1 - 1
SharixAdmin/urls.py

@@ -22,7 +22,7 @@ urlpatterns = [
     # Страница "О партнере"
     # Страница "О партнере"
     path('partner/', login_required(PartnerDetailView.as_view()), name='partner_detail'),
     path('partner/', login_required(PartnerDetailView.as_view()), name='partner_detail'),
     path('partner/edit/', login_required(PartnerEditView.as_view()), name='partner_edit'),
     path('partner/edit/', login_required(PartnerEditView.as_view()), name='partner_edit'),
-    path('partner/doc/<str:doc_code>', login_required(PartnerDocDetailView.as_view()), name='partner_doc'),
+    path('partner/doc/<str:doc_code>', login_required(PartnerDocEditView.as_view()), name='partner_doc_edit'),
 
 
 
 
     path('accounts/login/', LoginSharix.as_view(), name='authweb'),
     path('accounts/login/', LoginSharix.as_view(), name='authweb'),

+ 20 - 1
SharixAdmin/utils/ticket_gen.py

@@ -30,4 +30,23 @@ def create_ticket_partner_activation(user, сompany):
         """
         """
     )
     )
 
 
-    
+
+def create_ticket_partner_docs_verification(user, company, doc_name, doc_code):
+    """
+    Создание тикета на проверку документов партнера.
+    
+    Список: 2103, METASERVICE-ADMIN: Проверка документов (ST_REQUEST)
+    Тип: 1, ST_REQUEST
+    """
+    return Ticket.objects.create(
+        title=f"Проверка документа '{doc_name}' партнера '{company.legal_name}'",
+        ticket_list=TicketList.objects.get(pk=2103),
+        ticket_type=1,
+        due_date=datetime.now().date() + timedelta(days=30),
+        created_by=user,
+        
+        note=f"""
+            Пользователь {user} #{user.pk} добавил новые файлы документа '{doc_name}' партнера <a href="{company.get_admin_url()}">{company.legal_name}</a>
+            требующие проверки.
+        """
+    )    

+ 12 - 0
SharixAdmin/views/cooperate.py

@@ -8,6 +8,7 @@ from django.db import transaction
 
 
 from SharixAdmin.forms import CompanyForm
 from SharixAdmin.forms import CompanyForm
 from SharixAdmin.utils import create_ticket_partner_activation
 from SharixAdmin.utils import create_ticket_partner_activation
+from dbsynce.models import Documents
 from tickets.models import Ticket, TicketList
 from tickets.models import Ticket, TicketList
 
 
 
 
@@ -56,6 +57,17 @@ class CooperateView(UserPassesTestMixin, FormView):
             # Сохраняем новые изменения
             # Сохраняем новые изменения
             instance.save()
             instance.save()
 
 
+            # Создаем необходимые объекты документов по requirements указанных в созданной company
+            # Используем bulk_create для создания всех объектов одновременно
+            doc_codes = Documents.parse_requirements(instance.requirements)
+            Documents.objects.bulk_create([
+                Documents(
+                    company_id=instance,
+                    user_id=self.request.user,
+                    doc_type=doc_code
+                ) for doc_code in doc_codes
+            ])
+
         # Отправляем пользователю уведомление на страницу о успехе операции
         # Отправляем пользователю уведомление на страницу о успехе операции
         messages.success(self.request, 'Ваша заявка на становление партнером успешно отправлена и теперь проходит проверку!')
         messages.success(self.request, 'Ваша заявка на становление партнером успешно отправлена и теперь проходит проверку!')
 
 

+ 32 - 22
SharixAdmin/views/partner.py

@@ -1,15 +1,15 @@
 from django.views.generic import DetailView
 from django.views.generic import DetailView
 from django.views.generic.edit import FormView
 from django.views.generic.edit import FormView
 from django.urls import reverse_lazy
 from django.urls import reverse_lazy
-from django.shortcuts import get_object_or_404
+from django.shortcuts import get_object_or_404, redirect
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 from django.contrib.auth.mixins import UserPassesTestMixin
 from django.contrib.auth.mixins import UserPassesTestMixin
 from django.contrib import messages
 from django.contrib import messages
 from django.db import transaction
 from django.db import transaction
 
 
 from dbsynce.models import Company, Documents
 from dbsynce.models import Company, Documents
-from SharixAdmin.forms import CompanyForm
-from SharixAdmin.utils import create_ticket_partner_activation
+from SharixAdmin.forms import CompanyForm, DocumentUploadForm
+from SharixAdmin.utils import *
 
 
 from .base import BaseView
 from .base import BaseView
 
 
@@ -27,18 +27,19 @@ class PartnerDetailView(PartnerBaseView, DetailView):
     template_name = 'SharixAdmin/partner.html'
     template_name = 'SharixAdmin/partner.html'
     context_object_name = 'company'
     context_object_name = 'company'
     page_title = _('О партнере')
     page_title = _('О партнере')
-    
-
+   
     def get_object(self, queryset=None):
     def get_object(self, queryset=None):
         return get_object_or_404(Company, repr_id=self.request.user)
         return get_object_or_404(Company, repr_id=self.request.user)
 
 
     def get_context_data(self, **kwargs):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context = super().get_context_data(**kwargs)
 
 
-        context.update({
-            "doc_codes": Documents.parse_requirements(self.object.requirements),
-            "doc_dict": Documents.DOC_TYPES_DICT
-        }) 
+        docs = Documents.objects.filter(
+            user_id=self.request.user,
+            company_id=self.object
+        ).prefetch_related('files').order_by('doc_type')
+
+        context.update({ "docs": docs }) 
 
 
         return context
         return context
 
 
@@ -49,7 +50,6 @@ class PartnerEditView(PartnerBaseView, FormView):
     success_url = reverse_lazy('partner_detail')
     success_url = reverse_lazy('partner_detail')
     page_title = _('Изменение данных партнера')
     page_title = _('Изменение данных партнера')
 
 
-
     def get_form_kwargs(self):
     def get_form_kwargs(self):
         kwargs = super().get_form_kwargs()
         kwargs = super().get_form_kwargs()
         kwargs['instance'] = get_object_or_404(Company, repr_id=self.request.user)
         kwargs['instance'] = get_object_or_404(Company, repr_id=self.request.user)
@@ -68,22 +68,32 @@ class PartnerEditView(PartnerBaseView, FormView):
             current_company.ticket_status.archive()
             current_company.ticket_status.archive()
             create_ticket_partner_activation(self.request.user, current_company)
             create_ticket_partner_activation(self.request.user, current_company)
 
 
-        # Отправляем пользователю уведомление на страницу о успехе операции
+        # Отправляем полAьзователю уведомление на страницу об успехе операции
         messages.success(self.request, 'Данные успешно изменены и теперь проходят проверку!')
         messages.success(self.request, 'Данные успешно изменены и теперь проходят проверку!')
         return super().form_valid(form)
         return super().form_valid(form)
 
 
 
 
-class PartnerDocDetailView(PartnerBaseView, DetailView):       
+class PartnerDocEditView(PartnerBaseView, FormView):       
     template_name = 'SharixAdmin/partner_doc.html'
     template_name = 'SharixAdmin/partner_doc.html'
-    
-    def get_object(self, queryset=None):
-        doc_code = self.kwargs.get("doc_code")
-        self.page_title = _("Изменение документа партнера: ") + Documents.DOC_TYPES_DICT[doc_code]
+    form_class = DocumentUploadForm
+    success_url = reverse_lazy('partner_detail')
 
 
-        doc = Documents.objects.filter().first()
-        return doc
+    def dispatch(self, request, *args, **kwargs):
+        self.doc_code = kwargs.get("doc_code")
+        self.doc_name = Documents.DOC_TYPES_DICT[self.doc_code]
+        self.page_title = _("Изменение документа партнера: ") + self.doc_name
+        self.company = get_object_or_404(Company, repr_id=self.request.user)
+        return super().dispatch(request, *args, **kwargs)
 
 
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        
-        return context
+    def form_valid(self, form):
+        with transaction.atomic():
+            doc_file = self.request.FILES.getlist("doc_file")
+            
+            for file in doc_file:
+                print(file)
+
+            create_ticket_partner_docs_verification(self.request.user, self.company, self.doc_name, self.doc_code)
+
+        # Отправляем полAьзователю уведомление на страницу об успехе операции
+        messages.success(self.request, f'Файлы документа "{self.doc_name}" успешно загружены и теперь проходят проверку!')
+        return super().form_valid(form)