Добавлены кнопки Импорт и Экспорт на страницу списка клиентов
- Добавлены кнопки Импорт и Экспорт в header страницы customers/ - Создан URL-маршрут для customer-import и customer-export - Реализована функция customer_export: экспорт всех клиентов в CSV файл с BOM для Excel - Экспортируются поля: ID, Имя, Фамилия, Email, Телефон, Баланс кошелька, Дата создания - Создан шаблон customer_import.html с инструкцией и формой загрузки файла - Функция customer_import пока заглушка (TODO: реализовать парсинг CSV/Excel) - Кнопки оформлены в btn-group с иконками Bootstrap Icons - Системный клиент исключён из экспорта
This commit is contained in:
75
myproject/customers/templates/customers/customer_import.html
Normal file
75
myproject/customers/templates/customers/customer_import.html
Normal file
@@ -0,0 +1,75 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Импорт клиентов{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-md-8 offset-md-2">
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1>Импорт клиентов</h1>
|
||||
<a href="{% url 'customers:customer-list' %}" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left"></i> Назад к списку
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Инструкция -->
|
||||
<div class="alert alert-info mb-4">
|
||||
<h5 class="alert-heading"><i class="bi bi-info-circle"></i> Инструкция</h5>
|
||||
<p class="mb-2">Загрузите CSV или Excel файл со следующими столбцами:</p>
|
||||
<ul class="mb-2">
|
||||
<li><strong>Имя</strong> (обязательно)</li>
|
||||
<li><strong>Фамилия</strong> (опционально)</li>
|
||||
<li><strong>Email</strong> (опционально)</li>
|
||||
<li><strong>Телефон</strong> (опционально, формат: +375XXXXXXXXX)</li>
|
||||
<li><strong>Баланс кошелька</strong> (опционально, по умолчанию 0)</li>
|
||||
</ul>
|
||||
<p class="mb-0">
|
||||
<a href="{% url 'customers:customer-export' %}" class="btn btn-sm btn-outline-primary">
|
||||
<i class="bi bi-download"></i> Скачать образец (текущие клиенты)
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Форма загрузки -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="file" class="form-label">Выберите файл</label>
|
||||
<input type="file" class="form-control" id="file" name="file"
|
||||
accept=".csv,.xlsx,.xls" required>
|
||||
<small class="form-text text-muted">
|
||||
Поддерживаемые форматы: CSV, Excel (.xlsx, .xls)
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="form-check mb-3">
|
||||
<input type="checkbox" class="form-check-input" id="update_existing" name="update_existing">
|
||||
<label class="form-check-label" for="update_existing">
|
||||
Обновлять существующих клиентов (по email или телефону)
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<i class="bi bi-exclamation-triangle"></i>
|
||||
<strong>Внимание!</strong> Функция импорта находится в разработке.
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary" disabled>
|
||||
<i class="bi bi-upload"></i> Импортировать
|
||||
</button>
|
||||
<a href="{% url 'customers:customer-list' %}" class="btn btn-outline-secondary">
|
||||
Отмена
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -9,7 +9,17 @@
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h1>Клиенты</h1>
|
||||
<a href="{% url 'customers:customer-create' %}" class="btn btn-primary">Добавить клиента</a>
|
||||
<div class="btn-group" role="group">
|
||||
<a href="{% url 'customers:customer-import' %}" class="btn btn-outline-success">
|
||||
<i class="bi bi-upload"></i> Импорт
|
||||
</a>
|
||||
<a href="{% url 'customers:customer-export' %}" class="btn btn-outline-info">
|
||||
<i class="bi bi-download"></i> Экспорт
|
||||
</a>
|
||||
<a href="{% url 'customers:customer-create' %}" class="btn btn-primary">
|
||||
<i class="bi bi-plus-circle"></i> Добавить клиента
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search Form -->
|
||||
|
||||
@@ -6,6 +6,8 @@ app_name = 'customers'
|
||||
urlpatterns = [
|
||||
path('', views.customer_list, name='customer-list'),
|
||||
path('create/', views.customer_create, name='customer-create'),
|
||||
path('import/', views.customer_import, name='customer-import'),
|
||||
path('export/', views.customer_export, name='customer-export'),
|
||||
path('<int:pk>/', views.customer_detail, name='customer-detail'),
|
||||
path('<int:pk>/edit/', views.customer_update, name='customer-update'),
|
||||
path('<int:pk>/delete/', views.customer_delete, name='customer-delete'),
|
||||
|
||||
@@ -591,3 +591,69 @@ def wallet_withdraw(request, pk):
|
||||
messages.error(request, '; '.join(e.messages) if hasattr(e, 'messages') else str(e))
|
||||
|
||||
return redirect('customers:customer-detail', pk=pk)
|
||||
|
||||
|
||||
@login_required
|
||||
@manager_or_owner_required
|
||||
def customer_import(request):
|
||||
"""
|
||||
Импорт клиентов из CSV/Excel файла.
|
||||
TODO: Реализовать логику импорта
|
||||
"""
|
||||
if request.method == 'POST':
|
||||
# TODO: Обработка загруженного файла
|
||||
messages.info(request, 'Функция импорта в разработке')
|
||||
return redirect('customers:customer-list')
|
||||
|
||||
context = {
|
||||
'title': 'Импорт клиентов',
|
||||
}
|
||||
return render(request, 'customers/customer_import.html', context)
|
||||
|
||||
|
||||
@login_required
|
||||
@manager_or_owner_required
|
||||
def customer_export(request):
|
||||
"""
|
||||
Экспорт клиентов в CSV/Excel файл.
|
||||
TODO: Реализовать логику экспорта
|
||||
"""
|
||||
import csv
|
||||
from django.http import HttpResponse
|
||||
from django.utils import timezone
|
||||
|
||||
# Создаём HTTP ответ с CSV файлом
|
||||
response = HttpResponse(content_type='text/csv; charset=utf-8')
|
||||
response['Content-Disposition'] = f'attachment; filename="customers_export_{timezone.now().strftime("%Y%m%d_%H%M%S")}.csv"'
|
||||
|
||||
# Добавляем BOM для корректного открытия в Excel
|
||||
response.write('\ufeff')
|
||||
|
||||
writer = csv.writer(response)
|
||||
|
||||
# Заголовки
|
||||
writer.writerow([
|
||||
'ID',
|
||||
'Имя',
|
||||
'Фамилия',
|
||||
'Email',
|
||||
'Телефон',
|
||||
'Баланс кошелька',
|
||||
'Дата создания',
|
||||
])
|
||||
|
||||
# Данные (исключаем системного клиента)
|
||||
customers = Customer.objects.filter(is_system_customer=False).order_by('-created_at')
|
||||
|
||||
for customer in customers:
|
||||
writer.writerow([
|
||||
customer.id,
|
||||
customer.first_name or '',
|
||||
customer.last_name or '',
|
||||
customer.email or '',
|
||||
str(customer.phone) if customer.phone else '',
|
||||
str(customer.wallet_balance),
|
||||
customer.created_at.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
])
|
||||
|
||||
return response
|
||||
|
||||
Reference in New Issue
Block a user