Bläddra i källkod

Incomplete functionality of partner document upload

TonyKurts 3 månader sedan
förälder
incheckning
e65e38c552

+ 2 - 1
SharixAdmin/forms/__init__.py

@@ -1,3 +1,4 @@
 from .login import LoginUserForm
 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;
     height: 256px;
     padding: 2em;
+    width: 100%;
     border-radius: 10px;
     border: 2px dashed #55555597;
     color: #444;

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

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

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

@@ -34,14 +34,24 @@
 
 <h6 class="mb-4">Документы</h6>
     <ul class="list-style-none">
-        {% for doc_code in doc_codes %}
+        {% for doc in docs %}
             <li class="d-flex justify-content-between">
                 <div class="d-flex align-items-center">
                     <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>
-                  
-                <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>
         {% endfor %}
     </ul>

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

@@ -10,15 +10,56 @@
     Это система управления государством, источником власти в которой является сам народ. Именно народ решает, какие законы и нормы необходимы для гармоничного существования и развития государства.
 </p>
 
-<form>
+<form class="d-flex flex-column align-items-end" enctype="multipart/form-data" method="POST">
     {% 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>
 </form>
 {% 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/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'),

+ 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.utils import create_ticket_partner_activation
+from dbsynce.models import Documents
 from tickets.models import Ticket, TicketList
 
 
@@ -56,6 +57,17 @@ class CooperateView(UserPassesTestMixin, FormView):
             # Сохраняем новые изменения
             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, 'Ваша заявка на становление партнером успешно отправлена и теперь проходит проверку!')
 

+ 32 - 22
SharixAdmin/views/partner.py

@@ -1,15 +1,15 @@
 from django.views.generic import DetailView
 from django.views.generic.edit import FormView
 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.contrib.auth.mixins import UserPassesTestMixin
 from django.contrib import messages
 from django.db import transaction
 
 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
 
@@ -27,18 +27,19 @@ class PartnerDetailView(PartnerBaseView, DetailView):
     template_name = 'SharixAdmin/partner.html'
     context_object_name = 'company'
     page_title = _('О партнере')
-    
-
+   
     def get_object(self, queryset=None):
         return get_object_or_404(Company, repr_id=self.request.user)
 
     def get_context_data(self, **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
 
@@ -49,7 +50,6 @@ class PartnerEditView(PartnerBaseView, FormView):
     success_url = reverse_lazy('partner_detail')
     page_title = _('Изменение данных партнера')
 
-
     def get_form_kwargs(self):
         kwargs = super().get_form_kwargs()
         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()
             create_ticket_partner_activation(self.request.user, current_company)
 
-        # Отправляем пользователю уведомление на страницу о успехе операции
+        # Отправляем полAьзователю уведомление на страницу об успехе операции
         messages.success(self.request, 'Данные успешно изменены и теперь проходят проверку!')
         return super().form_valid(form)
 
 
-class PartnerDocDetailView(PartnerBaseView, DetailView):       
+class PartnerDocEditView(PartnerBaseView, FormView):       
     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)