183 lines
7.4 KiB
HTML
183 lines
7.4 KiB
HTML
{% extends 'mobile/mobile_base.html' %}
|
|
{% load static %}
|
|
{% load i18n %}
|
|
|
|
{% block title %}{% translate "Entrées / Sorties" %}{% endblock title %}
|
|
|
|
{% block upleft %}
|
|
<a href="{% url 'mobile:stock_index_mobile' %}" class="nav-link" style="color: white;">
|
|
<i class="bi bi-arrow-left fs-3"></i>
|
|
</a>
|
|
{% endblock upleft %}
|
|
|
|
{% block extra_head %}
|
|
<style>
|
|
.list-card {
|
|
border-radius: 0.75rem;
|
|
border: 1px solid #dee2e6;
|
|
background: #fff;
|
|
padding: 1rem;
|
|
margin-bottom: 0.75rem;
|
|
color: inherit;
|
|
box-shadow: 0 2px 6px rgba(47,62,139,0.06);
|
|
}
|
|
.list-card { cursor: default; }
|
|
.list-card-title { font-weight: 600; font-size: 1rem; }
|
|
.list-card-meta { font-size: 0.83rem; color: #6c757d; }
|
|
.list-card-link {
|
|
display: block;
|
|
text-decoration: none;
|
|
color: inherit;
|
|
border-radius: 0.5rem;
|
|
margin: -0.5rem -0.5rem 0;
|
|
padding: 0.5rem 0.5rem 0.5rem;
|
|
transition: background 0.15s;
|
|
}
|
|
.list-card-link:hover, .list-card-link:focus {
|
|
background: #f0f3ff;
|
|
color: inherit;
|
|
}
|
|
.article-item {
|
|
border-top: 1px solid #e9ecef;
|
|
padding-top: 0.4rem;
|
|
margin-top: 0.4rem;
|
|
font-size: 0.85rem;
|
|
}
|
|
.toggle-articles-btn { font-size: 0.8rem; }
|
|
</style>
|
|
{% endblock extra_head %}
|
|
|
|
{% block content %}
|
|
<div class="d-flex gap-2 mb-3">
|
|
<a href="{% url 'mobile:new_stock_entry_mobile' %}" class="btn btn-success flex-fill">
|
|
<i class="bi bi-box-arrow-in-down me-1"></i> {% translate "Entrée" %}
|
|
</a>
|
|
<a href="{% url 'mobile:new_stock_exit_mobile' %}" class="btn btn-danger flex-fill">
|
|
<i class="bi bi-box-arrow-up me-1"></i> {% translate "Sortie" %}
|
|
</a>
|
|
<a href="{% url 'mobile:new_stock_transfer_mobile' %}" class="btn btn-info text-dark flex-fill">
|
|
<i class="bi bi-arrow-left-right me-1"></i> {% translate "Transfert" %}
|
|
</a>
|
|
</div>
|
|
|
|
{% if batches %}
|
|
<div class="d-flex justify-content-end mb-2 px-1">
|
|
<button id="expand-all-btn" class="btn btn-outline-secondary btn-sm me-2" onclick="toggleAllCards(true)">
|
|
<i class="bi bi-arrows-expand me-1"></i> {% translate "Tout déplier" %}
|
|
</button>
|
|
<button id="collapse-all-btn" class="btn btn-outline-secondary btn-sm d-none" onclick="toggleAllCards(false)">
|
|
<i class="bi bi-arrows-collapse me-1"></i> {% translate "Tout replier" %}
|
|
</button>
|
|
</div>
|
|
{% for batch in batches %}
|
|
<div class="list-card">
|
|
<a href="{% url 'mobile:stock_movement_batch_detail_mobile' batch.pk %}" class="list-card-link">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<div>
|
|
<span class="list-card-title"># {{ batch.id }}</span>
|
|
</div>
|
|
{% if batch.movement_type == 'in' %}
|
|
<span class="badge bg-success">{% translate "Entrée" %}</span>
|
|
{% elif batch.movement_type == 'out' %}
|
|
<span class="badge bg-danger">{% translate "Sortie" %}</span>
|
|
{% elif batch.movement_type == 'transfer' %}
|
|
<span class="badge bg-info text-dark">{% translate "Transfert" %}</span>
|
|
{% else %}
|
|
<span class="badge bg-light text-dark">{{ batch.get_movement_type_display }}</span>
|
|
{% endif %}
|
|
</div>
|
|
<div class="list-card-meta mt-1">
|
|
<span class="me-3"><i class="bi bi-calendar3 me-1"></i>{{ batch.date|date:"d/m/Y H:i" }}</span>
|
|
</div>
|
|
{% if batch.movement_type != 'transfer' %}
|
|
{% if batch.person %}
|
|
<div class="list-card-meta mt-1">
|
|
<i class="bi bi-person me-1"></i>{{ batch.person.name }}
|
|
</div>
|
|
{% elif batch.company %}
|
|
<div class="list-card-meta mt-1">
|
|
<i class="bi bi-building me-1"></i>{{ batch.company.name }}
|
|
</div>
|
|
{% endif %}
|
|
{% endif %}
|
|
{% if batch.created_by %}
|
|
<div class="list-card-meta mt-1">
|
|
<i class="bi bi-person-gear me-1"></i>{{ batch.created_by.get_full_name|default:batch.created_by.username }}
|
|
</div>
|
|
{% endif %}
|
|
{% if batch.reason %}
|
|
<div class="list-card-meta mt-1 text-truncate">
|
|
<i class="bi bi-chat-left-text me-1"></i>{{ batch.reason|truncatechars:60 }}
|
|
</div>
|
|
{% endif %}
|
|
</a>
|
|
{% with movements=batch.movements.all %}
|
|
{% if movements %}
|
|
<button class="btn btn-link toggle-articles-btn p-0 mt-2 text-decoration-none"
|
|
type="button"
|
|
data-bs-toggle="collapse"
|
|
data-bs-target="#batch-articles-{{ batch.pk }}"
|
|
aria-expanded="false"
|
|
aria-controls="batch-articles-{{ batch.pk }}">
|
|
<i class="bi bi-chevron-right me-1 toggle-icon-{{ batch.pk }}"></i>
|
|
<span class="text-muted">{{ movements|length }} {% translate "article(s)" %}</span>
|
|
</button>
|
|
<div class="collapse batch-articles" id="batch-articles-{{ batch.pk }}">
|
|
{% for movement in movements %}
|
|
<div class="article-item">
|
|
<div class="fw-semibold">{{ movement.product.name }}</div>
|
|
<div class="d-flex justify-content-between list-card-meta">
|
|
<span>
|
|
<i class="bi bi-geo me-1"></i>
|
|
{{ movement.source_location.name|default:"—" }} → {{ movement.destination_location.name|default:"—" }}
|
|
</span>
|
|
<span>
|
|
{% if movement.source_location and movement.destination_location %}
|
|
{{ movement.quantity }}
|
|
{% elif movement.destination_location %}
|
|
<span class="text-success">+{{ movement.quantity }}</span>
|
|
{% else %}
|
|
<span class="text-danger">-{{ movement.quantity }}</span>
|
|
{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
{% endwith %}
|
|
</div>
|
|
{% endfor %}
|
|
{% else %}
|
|
<div class="text-center text-muted py-5">
|
|
<i class="bi bi-arrow-left-right fs-1 d-block mb-2"></i>
|
|
{% translate "Aucun mouvement de stock." %}
|
|
</div>
|
|
{% endif %}
|
|
{% endblock content %}
|
|
|
|
{% block extra_scripts %}
|
|
<script>
|
|
document.querySelectorAll('[data-bs-toggle="collapse"].toggle-articles-btn').forEach(function(btn) {
|
|
var target = btn.getAttribute('data-bs-target');
|
|
var collapseEl = document.querySelector(target);
|
|
if (collapseEl) {
|
|
collapseEl.addEventListener('show.bs.collapse', function() {
|
|
btn.querySelector('i').classList.replace('bi-chevron-right', 'bi-chevron-down');
|
|
});
|
|
collapseEl.addEventListener('hide.bs.collapse', function() {
|
|
btn.querySelector('i').classList.replace('bi-chevron-down', 'bi-chevron-right');
|
|
});
|
|
}
|
|
});
|
|
|
|
function toggleAllCards(expand) {
|
|
document.querySelectorAll('.batch-articles').forEach(function(el) {
|
|
var bsCollapse = bootstrap.Collapse.getOrCreateInstance(el, { toggle: false });
|
|
if (expand) { bsCollapse.show(); } else { bsCollapse.hide(); }
|
|
});
|
|
document.getElementById('expand-all-btn').classList.toggle('d-none', expand);
|
|
document.getElementById('collapse-all-btn').classList.toggle('d-none', !expand);
|
|
}
|
|
</script>
|
|
{% endblock extra_scripts %}
|