Files
MES_Core/shiftflow/templates/shiftflow/closing.html
2026-04-13 07:36:57 +03:00

288 lines
13 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends 'base.html' %}
{% block content %}
<div class="card border-secondary mb-3 shadow-sm">
<div class="card-body py-2">
<form method="get" class="row g-2 align-items-center">
<div class="col-md-4">
<label class="small text-muted mb-1 fw-bold">Станок:</label>
<select class="form-select form-select-sm bg-body text-body border-secondary" name="machine_id" onchange="this.form.submit()">
<option value="">— выбрать —</option>
{% for m in machines %}
<option value="{{ m.id }}" {% if selected_machine_id == m.id|stringformat:"s" %}selected{% endif %}>{{ m.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-6">
<label class="small text-muted mb-1 fw-bold">Материал:</label>
<select class="form-select form-select-sm bg-body text-body border-secondary" name="material_id" onchange="this.form.submit()">
<option value="">— выбрать —</option>
{% for mat in materials %}
<option value="{{ mat.id }}" {% if selected_material_id == mat.id|stringformat:"s" %}selected{% endif %}>{{ mat.full_name|default:mat.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-2 text-end mt-auto">
<a class="btn btn-outline-secondary btn-sm w-100" href="{% url 'closing' %}">Сброс</a>
</div>
</form>
</div>
</div>
<form method="post">
{% csrf_token %}
<input type="hidden" name="machine_id" value="{{ selected_machine_id }}">
<input type="hidden" name="material_id" value="{{ selected_material_id }}">
<div class="card shadow border-secondary mb-3">
<div class="card-header border-secondary py-3 d-flex justify-content-between align-items-center">
<h3 class="text-accent mb-0"><i class="bi bi-check2-square me-2"></i>Закрытие</h3>
</div>
<div class="table-responsive">
<table class="table table-hover mb-0 align-middle">
<thead>
<tr class="table-custom-header">
<th>Дата</th>
<th>Сделка</th>
<th>Деталь</th>
<th>К закрытию</th>
<th data-sort="false">Факт</th>
<th data-sort="false">Режим</th>
</tr>
</thead>
<tbody>
{% for wi in workitems %}
<tr>
<td class="small">{{ wi.date|date:"d.m.Y" }}</td>
<td><span class="text-accent fw-bold">{{ wi.deal.number }}</span></td>
<td class="fw-bold">{{ wi.entity.drawing_number|default:"—" }} {{ wi.entity.name }}</td>
<td>{{ wi.remaining }}</td>
<td style="max-width:140px;">
<input class="form-control form-control-sm border-secondary" type="number" min="0" max="{{ wi.remaining }}" name="fact_{{ wi.id }}" id="fact_{{ wi.id }}" value="0" {% if not can_edit %}disabled{% endif %}>
</td>
<td style="min-width:260px;">
<div class="d-flex gap-2 align-items-center flex-wrap">
<button type="button" class="btn btn-sm btn-outline-success closing-set-action" data-item-id="{{ wi.id }}" data-action="done" data-plan="{{ wi.remaining }}" {% if not can_edit %}disabled{% endif %}>Полностью</button>
<button type="button" class="btn btn-sm btn-outline-warning closing-set-action" data-item-id="{{ wi.id }}" data-action="partial" data-plan="{{ wi.remaining }}" {% if not can_edit %}disabled{% endif %}>Частично</button>
<input type="hidden" id="ca_{{ wi.id }}" name="close_action_{{ wi.id }}" value="">
<span class="small text-muted" id="modeLabel_{{ wi.id }}"></span>
</div>
</td>
</tr>
{% empty %}
<tr><td colspan="6" class="text-center text-muted py-4">Выбери станок и материал</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="card shadow border-secondary mb-3">
<div class="card-header border-secondary py-3">
<h5 class="mb-0">Списание со склада цеха (единицы)</h5>
</div>
<div class="table-responsive">
<table class="table table-hover mb-0 align-middle">
<thead>
<tr class="table-custom-header">
<th>Поступление</th>
<th>Сделка</th>
<th>Единица</th>
<th>Размеры</th>
<th>Доступно</th>
<th data-sort="false">Использовано</th>
</tr>
</thead>
<tbody>
{% for s in stock_items %}
<tr>
<td class="small">{% if s.created_at %}{{ s.created_at|date:"d.m.Y H:i" }}{% endif %}</td>
<td>
{% if s.deal_id %}
<span class="text-accent fw-bold">{{ s.deal.number }}</span>
{% else %}
{% endif %}
</td>
<td>{{ s }}</td>
<td>
{% if s.current_length and s.current_width %}
{{ s.current_length|floatformat:"-g" }} × {{ s.current_width|floatformat:"-g" }} мм
{% elif s.current_length %}
{{ s.current_length|floatformat:"-g" }} мм
{% else %}
{% endif %}
</td>
<td>{{ s.quantity }}</td>
<td style="max-width:140px;">
<input class="form-control form-control-sm border-secondary" name="consume_{{ s.id }}" placeholder="0" {% if not can_edit %}disabled{% endif %}>
</td>
</tr>
{% empty %}
<tr><td colspan="5" class="text-center text-muted py-4">Нет единиц на складе для выбранного материала</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<div class="card shadow border-secondary">
<div class="card-header border-secondary py-3 d-flex justify-content-between align-items-center">
<h5 class="mb-0">Остаток ДО</h5>
<button type="button" class="btn btn-outline-accent btn-sm" id="addRemnantBtn" {% if not can_edit %}disabled{% endif %}>Добавить ДО</button>
</div>
<div class="table-responsive">
<table class="table table-hover mb-0 align-middle">
<thead>
<tr class="table-custom-header">
<th>Кол-во</th>
<th>Длина (мм)</th>
<th>Ширина (мм)</th>
<th data-sort="false"></th>
</tr>
</thead>
<tbody id="remnantBody">
<tr id="remnantEmptyRow">
<td colspan="4" class="text-center text-muted py-4">ДО не добавлены</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="d-flex justify-content-end mt-3">
<button type="submit" class="btn btn-outline-accent" {% if not can_edit %}disabled{% endif %}>Сохранить</button>
</div>
</form>
<script>
document.addEventListener('DOMContentLoaded', () => {
const canEdit = {% if can_edit %}true{% else %}false{% endif %};
document.querySelectorAll('.closing-set-action').forEach(btn => {
btn.addEventListener('click', () => {
if (!canEdit) return;
const itemId = btn.getAttribute('data-item-id');
const action = btn.getAttribute('data-action');
const plan = parseInt(btn.getAttribute('data-plan') || '0', 10) || 0;
const hidden = document.getElementById('ca_' + itemId);
const fact = document.getElementById('fact_' + itemId);
const label = document.getElementById('modeLabel_' + itemId);
if (hidden) hidden.value = action;
const cell = btn.closest('td');
if (cell) {
cell.querySelectorAll('.closing-set-action').forEach(b => {
const a = b.getAttribute('data-action');
if (a === 'done') {
b.classList.remove('btn-success');
b.classList.add('btn-outline-success');
}
if (a === 'partial') {
b.classList.remove('btn-warning');
b.classList.add('btn-outline-warning');
}
});
}
if (action === 'done') {
btn.classList.remove('btn-outline-success');
btn.classList.add('btn-success');
if (fact) {
fact.value = String(plan);
fact.readOnly = true;
}
if (label) label.textContent = 'Выбрано: полностью';
}
if (action === 'partial') {
btn.classList.remove('btn-outline-warning');
btn.classList.add('btn-warning');
if (fact) {
fact.readOnly = false;
fact.focus();
fact.select();
}
if (label) label.textContent = 'Выбрано: частично';
}
});
});
const addBtn = document.getElementById('addRemnantBtn');
const body = document.getElementById('remnantBody');
const emptyRow = document.getElementById('remnantEmptyRow');
function renumberRemnants() {
const rows = Array.from(body.querySelectorAll('tr[data-remnant-row="1"]'));
rows.forEach((tr, idx) => {
const qty = tr.querySelector('input[data-field="qty"]');
const len = tr.querySelector('input[data-field="len"]');
const wid = tr.querySelector('input[data-field="wid"]');
if (qty) qty.name = 'remnant_qty_' + idx;
if (len) len.name = 'remnant_len_' + idx;
if (wid) wid.name = 'remnant_wid_' + idx;
});
if (emptyRow) {
emptyRow.style.display = rows.length ? 'none' : '';
}
}
function addRemnantRow() {
if (!canEdit) return;
const rows = Array.from(body.querySelectorAll('tr[data-remnant-row="1"]'));
if (rows.length >= 50) return;
const tr = document.createElement('tr');
tr.setAttribute('data-remnant-row', '1');
tr.innerHTML = `
<td style="max-width:180px;">
<input class="form-control form-control-sm border-secondary" data-field="qty" inputmode="decimal" placeholder="Кол-во" required>
</td>
<td style="max-width:180px;">
<input class="form-control form-control-sm border-secondary" data-field="len" inputmode="decimal" placeholder="Длина (мм)">
</td>
<td style="max-width:180px;">
<input class="form-control form-control-sm border-secondary" data-field="wid" inputmode="decimal" placeholder="Ширина (мм)">
</td>
<td class="text-end">
<button type="button" class="btn btn-outline-secondary btn-sm" data-action="remove">Удалить</button>
</td>
`;
const rm = tr.querySelector('button[data-action="remove"]');
if (rm) {
rm.addEventListener('click', () => {
tr.remove();
renumberRemnants();
});
}
body.appendChild(tr);
renumberRemnants();
const first = tr.querySelector('input[data-field="qty"]');
if (first) {
first.focus();
first.select();
}
}
if (addBtn) {
addBtn.addEventListener('click', addRemnantRow);
}
renumberRemnants();
});
</script>
{% endblock %}