295 lines
20 KiB
HTML
295 lines
20 KiB
HTML
{% extends 'base.html' %}
|
||
{% load static %}
|
||
|
||
{% block content %}
|
||
<div class="container-fluid py-4">
|
||
<div class="row">
|
||
<!-- Sidebar: Info & QR -->
|
||
<div class="col-lg-4">
|
||
<div class="card shadow-sm border-0 mb-4">
|
||
{% if unit.photo %}
|
||
<img src="{{ unit.photo.url }}" class="card-img-top" alt="{{ unit.name }}" style="height: 250px; object-fit: cover;">
|
||
{% else %}
|
||
<div class="bg-light text-center py-5">
|
||
<i class="bi bi-truck text-muted display-1"></i>
|
||
</div>
|
||
{% endif %}
|
||
<div class="card-body">
|
||
<div class="d-flex justify-content-between align-items-start mb-3">
|
||
<div>
|
||
<h4 class="fw-bold mb-0">{{ unit.name }}</h4>
|
||
<span class="text-muted small">{{ unit.model_name }}</span>
|
||
</div>
|
||
<span class="badge bg-{{ unit.get_status_color }} rounded-pill px-3 py-2">
|
||
{{ unit.get_status_display }}
|
||
</span>
|
||
</div>
|
||
|
||
<div class="row g-3 mb-4">
|
||
<div class="col-6">
|
||
<p class="text-muted small mb-0">Госномер</p>
|
||
<p class="fw-bold mb-0">{{ unit.plate_number|default:"-" }}</p>
|
||
</div>
|
||
<div class="col-6">
|
||
<p class="text-muted small mb-0">Год выпуска</p>
|
||
<p class="fw-bold mb-0">{{ unit.year }}</p>
|
||
</div>
|
||
<div class="col-12">
|
||
<p class="text-muted small mb-0">VIN / Серийный номер</p>
|
||
<p class="fw-bold mb-0">{{ unit.vin }}</p>
|
||
</div>
|
||
</div>
|
||
|
||
{% if unit.insurance_company %}
|
||
<div class="bg-light p-3 rounded mb-4">
|
||
<h6 class="fw-bold small mb-2"><i class="bi bi-shield-check me-2"></i>Страховка</h6>
|
||
<p class="small mb-1"><strong>Компания:</strong> {{ unit.insurance_company }}</p>
|
||
<p class="small mb-1"><strong>Полис:</strong> {{ unit.insurance_policy_number|default:"-" }}</p>
|
||
<p class="small mb-0"><strong>Срок:</strong> {{ unit.insurance_start_date|date:"d.m.Y" }} — {{ unit.insurance_end_date|date:"d.m.Y" }}</p>
|
||
</div>
|
||
{% endif %}
|
||
|
||
<div class="d-grid gap-2">
|
||
<a href="{% url 'fleet_edit' unit.pk %}" class="btn btn-outline-primary rounded-pill">Редактировать</a>
|
||
{% if user.is_staff %}
|
||
<form action="{% url 'fleet_delete' unit.pk %}" method="POST" class="d-inline" onsubmit="return confirm('Вы уверены, что хотите удалить эту единицу техники? Все связанные данные будут удалены.')">
|
||
{% csrf_token %}
|
||
<button type="submit" class="btn btn-outline-danger rounded-pill w-100 mb-2">Удалить технику</button>
|
||
</form>
|
||
{% endif %}
|
||
<a href="{% url 'breakdown_add' %}?fleet_unit={{ unit.pk }}" class="btn btn-danger rounded-pill">Заявить о поломке</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow-sm border-0 text-center p-4">
|
||
<h6 class="fw-bold mb-3">QR-код техники</h6>
|
||
{% if unit.qr_code %}
|
||
<img src="{{ unit.qr_code.url }}" class="img-fluid mx-auto mb-3" style="max-width: 150px;" alt="QR Code">
|
||
{% else %}
|
||
<div class="alert alert-light small">QR-код генерируется...</div>
|
||
{% endif %}
|
||
<p class="text-muted small mb-0">Наклейте этот код на технику для быстрого доступа механика.</p>
|
||
<button onclick="window.print()" class="btn btn-sm btn-link mt-2">Печать кода</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Main Content: Tabs -->
|
||
<div class="col-lg-8">
|
||
<div class="card shadow-sm border-0">
|
||
<div class="card-header bg-white border-0 pt-3">
|
||
<ul class="nav nav-pills" id="fleetTab" role="tablist">
|
||
<li class="nav-item">
|
||
<button class="nav-link active rounded-pill px-4" id="history-tab" data-bs-toggle="tab" data-bs-target="#history" type="button">История ТО</button>
|
||
</li>
|
||
<li class="nav-item">
|
||
<button class="nav-link rounded-pill px-4" id="breakdowns-tab" data-bs-toggle="tab" data-bs-target="#breakdowns" type="button">Поломки</button>
|
||
</li>
|
||
<li class="nav-item">
|
||
<button class="nav-link rounded-pill px-4" id="parts-tab" data-bs-toggle="tab" data-bs-target="#parts" type="button">Заявки на запчасти</button>
|
||
</li>
|
||
<li class="nav-item">
|
||
<button class="nav-link rounded-pill px-4" id="supply-tab" data-bs-toggle="tab" data-bs-target="#supply" type="button">Снабжение</button>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="tab-content" id="fleetTabContent">
|
||
<!-- Maintenance Tab -->
|
||
<div class="tab-pane fade show active" id="history">
|
||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||
<h6 class="fw-bold mb-0">Плановое и выполненное ТО</h6>
|
||
<a href="{% url 'maintenance_add' %}?fleet_unit={{ unit.pk }}" class="btn btn-sm btn-primary rounded-pill">+ Запланировать</a>
|
||
</div>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm align-middle">
|
||
<thead>
|
||
<tr>
|
||
<th>Тип</th>
|
||
<th>Дата</th>
|
||
<th>Статус</th>
|
||
<th>Исполнитель</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for m in maintenances %}
|
||
<tr>
|
||
<td>{{ m.m_type }}</td>
|
||
<td>{{ m.planned_date }}</td>
|
||
<td><span class="badge bg-{{ m.status|yesno:'success,warning,secondary' }} rounded-pill small">{{ m.get_status_display }}</span></td>
|
||
<td>{{ m.mechanic|default:"-" }}</td>
|
||
<td class="text-end">
|
||
<div class="btn-group">
|
||
<a href="{% url 'maintenance_detail' m.pk %}" class="btn btn-sm btn-link text-primary p-0 me-2">Открыть</a>
|
||
{% if user.is_staff %}
|
||
<form action="{% url 'maintenance_delete' m.pk %}" method="POST" class="d-inline" onsubmit="return confirm('Удалить запись ТО?')">
|
||
{% csrf_token %}
|
||
<button type="submit" class="btn btn-sm btn-link text-danger p-0"><i class="bi bi-trash"></i></button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
{% empty %}
|
||
<tr><td colspan="5" class="text-center py-4 text-muted">Нет записей ТО</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Breakdowns Tab -->
|
||
<div class="tab-pane fade" id="breakdowns">
|
||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||
<h6 class="fw-bold mb-0">Журнал поломок</h6>
|
||
<a href="{% url 'breakdown_add' %}?fleet_unit={{ unit.pk }}" class="btn btn-sm btn-danger rounded-pill">+ Новая поломка</a>
|
||
</div>
|
||
<div class="list-group list-group-flush">
|
||
{% for b in breakdowns %}
|
||
<div class="list-group-item px-0 py-3">
|
||
<div class="d-flex justify-content-between mb-1">
|
||
<h6 class="mb-0 fw-bold text-danger">{{ b.system_node }}</h6>
|
||
<div>
|
||
<span class="badge bg-light text-dark border small me-2">{{ b.get_status_display }}</span>
|
||
{% if user.is_staff %}
|
||
<form action="{% url 'breakdown_delete' b.pk %}" method="POST" class="d-inline" onsubmit="return confirm('Удалить запись о поломке?')">
|
||
{% csrf_token %}
|
||
<button type="submit" class="btn btn-sm btn-link text-danger p-0"><i class="bi bi-trash"></i></button>
|
||
</form>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
<p class="small mb-1 text-muted">{{ b.date|date:"d.m.Y" }} — {{ b.description }}</p>
|
||
<div class="d-flex align-items-center mt-2">
|
||
<a href="{% url 'part_request_add' %}?breakdown={{ b.pk }}" class="btn btn-sm btn-outline-primary rounded-pill py-0 small me-2">+ Заказать запчасть</a>
|
||
{% if b.photo %}<span class="badge bg-light text-muted border small"><i class="bi bi-image me-1"></i>Есть фото</span>{% endif %}
|
||
</div>
|
||
</div>
|
||
{% empty %}
|
||
<div class="text-center py-4 text-muted">Поломок не зафиксировано</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Parts Tab -->
|
||
<div class="tab-pane fade" id="parts">
|
||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||
<h6 class="fw-bold mb-0">Заявки на запчасти</h6>
|
||
<a href="{% url 'part_request_add' %}?fleet_unit={{ unit.pk }}" class="btn btn-sm btn-primary rounded-pill">+ Создать заявку</a>
|
||
</div>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm align-middle">
|
||
<thead>
|
||
<tr>
|
||
<th>Деталь</th>
|
||
<th>Кол-во</th>
|
||
<th>Статус</th>
|
||
<th>Дата</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for r in part_requests %}
|
||
<tr>
|
||
<td>{{ r.part_name }}</td>
|
||
<td>{{ r.quantity }}</td>
|
||
<td><span class="badge bg-light text-dark border rounded-pill small">{{ r.get_status_display }}</span></td>
|
||
<td class="small">{{ r.created_at|date:"d.m.Y" }}</td>
|
||
<td class="text-end">
|
||
{% if user.is_staff %}
|
||
<form action="{% url 'part_request_delete' r.pk %}" method="POST" class="d-inline" onsubmit="return confirm('Удалить заявку?')">
|
||
{% csrf_token %}
|
||
<button type="submit" class="btn btn-sm btn-link text-danger p-0"><i class="bi bi-trash"></i></button>
|
||
</form>
|
||
{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% empty %}
|
||
<tr><td colspan="5" class="text-center py-4 text-muted">Нет заявок</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Supply Tab -->
|
||
<div class="tab-pane fade" id="supply">
|
||
<h6 class="fw-bold mb-3">Данные по снабжению и поставщику</h6>
|
||
<div class="row g-4">
|
||
<div class="col-md-6">
|
||
{% if unit.supplier %}
|
||
<p class="text-muted small mb-1">Поставщик / Контрагент</p>
|
||
<p class="fw-bold mb-1">{{ unit.supplier.name }}</p>
|
||
<p class="small text-muted mb-3">Договор №{{ unit.supplier.contract_number|default:"-" }}</p>
|
||
|
||
<p class="text-muted small mb-1">Представитель</p>
|
||
<p class="small mb-1">{{ unit.supplier.representative_name|default:"-" }}</p>
|
||
<p class="small mb-1"><i class="bi bi-telephone me-2"></i>{{ unit.supplier.phone|default:"-" }}</p>
|
||
<p class="small"><i class="bi bi-envelope me-2"></i>{{ unit.supplier.email|default:"-" }}</p>
|
||
{% else %}
|
||
<p class="text-muted small">Поставщик не привязан</p>
|
||
<p class="small text-muted">Вы можете выбрать поставщика в режиме редактирования техники.</p>
|
||
{% endif %}
|
||
</div>
|
||
<div class="col-md-6 text-end">
|
||
<p class="text-muted small mb-1">Документы на авто</p>
|
||
{% if unit.vehicle_documents %}
|
||
<a href="{{ unit.vehicle_documents.url }}" class="btn btn-outline-secondary btn-sm rounded-pill" target="_blank">
|
||
<i class="bi bi-file-earmark-text me-2"></i>Открыть документы
|
||
</a>
|
||
{% else %}
|
||
<p class="text-muted small">Не загружены</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<hr class="my-4">
|
||
|
||
<h6 class="fw-bold mb-3">Связанные заявки на запчасти</h6>
|
||
<div class="table-responsive">
|
||
<table class="table table-sm align-middle">
|
||
<thead>
|
||
<tr>
|
||
<th>Деталь</th>
|
||
<th>Статус</th>
|
||
<th>Дата</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for r in part_requests %}
|
||
<tr>
|
||
<td>{{ r.part_name }}</td>
|
||
<td><span class="badge bg-light text-dark border rounded-pill small">{{ r.get_status_display }}</span></td>
|
||
<td class="small">{{ r.created_at|date:"d.m.Y" }}</td>
|
||
<td class="text-end">
|
||
{% if user.is_staff %}
|
||
<form action="{% url 'part_request_delete' r.pk %}" method="POST" class="d-inline" onsubmit="return confirm('Удалить заявку?')">
|
||
{% csrf_token %}
|
||
<button type="submit" class="btn btn-sm btn-link text-danger p-0"><i class="bi bi-trash"></i></button>
|
||
</form>
|
||
{% endif %}
|
||
</td>
|
||
</tr>
|
||
{% empty %}
|
||
<tr><td colspan="4" class="text-center py-4 text-muted">Нет заявок</td></tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow-sm border-0 mt-4">
|
||
<div class="card-header bg-white fw-bold">Примечания</div>
|
||
<div class="card-body">
|
||
<p class="mb-0">{{ unit.notes|default:"Нет примечаний" }}</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endblock %} |