Files
watersurf-erp/app/templates/documents/supplier_order_form.html

196 lines
7.7 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 title %}{{ title }} — ERP WaterSurf{% endblock %}
{% block content %}
<div class="ws-card">
<h2 class="ws-page-title">{% if object %}Редактировать{% else %}Создать{% endif %} {{ title }}</h2>
<form method="post" class="ws-form-card ws-form-compact">
{% csrf_token %}
<div class="ws-form-row ws-form-row-date-number">
<div class="ws-form-group ws-field-date">
<label for="{{ form.date.id_for_label }}">{{ form.date.label }}</label>
{{ form.date }}
{% if form.date.errors %}<small class="ws-text-danger">{{ form.date.errors.0 }}</small>{% endif %}
</div>
<div class="ws-form-group ws-field-number">
<label for="{{ form.number.id_for_label }}">{{ form.number.label }}</label>
{{ form.number }}
{% if form.number.errors %}<small class="ws-text-danger">{{ form.number.errors.0 }}</small>{% endif %}
</div>
</div>
<div class="ws-form-row ws-form-row-2">
<div class="ws-form-group">
<label for="{{ form.organization.id_for_label }}">{{ form.organization.label }}</label>
{{ form.organization }}
{% if form.organization.errors %}<small class="ws-text-danger">{{ form.organization.errors.0 }}</small>{% endif %}
</div>
<div class="ws-form-group">
<label for="{{ form.supplier.id_for_label }}">{{ form.supplier.label }}</label>
{{ form.supplier }}
{% if form.supplier.errors %}<small class="ws-text-danger">{{ form.supplier.errors.0 }}</small>{% endif %}
</div>
</div>
<div class="ws-form-row ws-form-row-2">
<div class="ws-form-group">
<label for="{{ form.currency.id_for_label }}">{{ form.currency.label }}</label>
{{ form.currency }}
{% if form.currency.errors %}<small class="ws-text-danger">{{ form.currency.errors.0 }}</small>{% endif %}
</div>
<div class="ws-form-group">
<label for="{{ form.rate.id_for_label }}">{{ form.rate.label }}</label>
{{ form.rate }}
{% if form.rate.errors %}<small class="ws-text-danger">{{ form.rate.errors.0 }}</small>{% endif %}
</div>
</div>
<div class="ws-form-row ws-form-row-2">
<div class="ws-form-group">
<label for="{{ form.author.id_for_label }}">{{ form.author.label }}</label>
{{ form.author }}
{% if form.author.errors %}<small class="ws-text-danger">{{ form.author.errors.0 }}</small>{% endif %}
</div>
</div>
<div class="ws-form-section">
<h3 class="ws-form-section-title">Товары</h3>
{{ formset.management_form }}
<div class="ws-table-wrap">
<table class="ws-table ws-table-items" id="supplier-order-items">
<colgroup>
<col class="ws-col-product">
<col class="ws-col-price">
<col class="ws-col-currency">
<col class="ws-col-qty">
<col class="ws-col-cost">
<col class="ws-col-del">
</colgroup>
<thead>
<tr>
<th>Товар</th>
<th>Цена</th>
<th>Валюта</th>
<th>Количество</th>
<th class="ws-num">Стоимость</th>
<th>Удалить</th>
</tr>
</thead>
<tbody id="supplier-order-items-body">
{% for f in formset %}
<tr class="item-row">
<td class="ws-col-product">{{ f.id }}{{ f.product }}</td>
<td class="ws-col-price">{{ f.price }}</td>
<td class="ws-col-currency">{{ f.currency }}</td>
<td class="ws-col-qty">{{ f.quantity }}</td>
<td class="row-amount ws-col-cost ws-num"></td>
<td class="ws-col-del"><button type="button" class="ws-btn-remove-row" title="Удалить строку" aria-label="Удалить строку">×</button></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="ws-btn-group" style="margin-top: 0.75rem;">
<button type="button" class="btn btn-ws-secondary" id="add-supplier-order-row">+ Добавить строку</button>
</div>
</div>
<div class="ws-btn-group" style="margin-top: 1.25rem;">
<button type="submit" class="btn btn-ws-primary">Сохранить</button>
<a href="{% url 'documents:supplier_order_list' %}" class="btn btn-ws-secondary">Отмена</a>
</div>
</form>
</div>
<script>
(function() {
var form = document.querySelector('.ws-form-card');
var tbody = document.getElementById('supplier-order-items-body');
var totalInput = form.querySelector('input[name$="-TOTAL_FORMS"]');
if (!totalInput || !tbody) return;
function getPrefix() {
var name = totalInput.getAttribute('name');
return name.replace(/-TOTAL_FORMS$/, '');
}
function formatNum(x) {
var n = parseFloat(x);
if (isNaN(n)) return '—';
var parts = n.toFixed(2).split('.');
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, '\u202f');
return parts.join(',');
}
function parseNum(s) {
return parseFloat(String(s).replace(/\s/g, '').replace(',', '.')) || 0;
}
function updateRowAmounts() {
document.querySelectorAll('#supplier-order-items .item-row').forEach(function(row) {
var priceInput = row.querySelector('input[name$="-price"]');
var qty = parseNum(row.querySelector('input[name$="-quantity"]')?.value);
var price = parseNum(priceInput?.value);
var el = row.querySelector('.row-amount');
if (el) el.textContent = formatNum(price * qty);
});
}
form.addEventListener('input', updateRowAmounts);
form.addEventListener('submit', function() {
form.querySelectorAll('input[name$="-price"]').forEach(function(input) {
input.value = String(input.value).replace(/\s/g, '').replace(',', '.');
});
});
updateRowAmounts();
function reindexRows() {
var prefix = getPrefix();
var rows = tbody.querySelectorAll('.item-row');
rows.forEach(function(row, i) {
row.querySelectorAll('input, select').forEach(function(el) {
var n = el.getAttribute('name');
if (n && n.indexOf(prefix) === 0) {
el.setAttribute('name', n.replace(new RegExp('^' + prefix + '\\d+'), prefix + i));
}
var id = el.getAttribute('id');
if (id) {
el.setAttribute('id', id.replace(new RegExp(prefix + '\\d+'), prefix + i));
}
});
});
totalInput.value = String(rows.length);
updateRowAmounts();
}
tbody.addEventListener('click', function(e) {
var btn = e.target.closest('.ws-btn-remove-row');
if (!btn) return;
var row = btn.closest('tr.item-row');
if (!row) return;
row.remove();
reindexRows();
});
document.getElementById('add-supplier-order-row').addEventListener('click', function() {
var rows = tbody.querySelectorAll('.item-row');
var lastRow = rows[rows.length - 1];
if (!lastRow) return;
var prefix = getPrefix();
var nextIndex = parseInt(totalInput.value, 10);
var clone = lastRow.cloneNode(true);
clone.querySelectorAll('input, select').forEach(function(el) {
var name = el.getAttribute('name');
if (name && name.indexOf(prefix) === 0) {
el.setAttribute('name', name.replace(new RegExp('^' + prefix + '\\d+-'), prefix + nextIndex + '-'));
el.setAttribute('id', (el.getAttribute('id') || '').replace(new RegExp(prefix + '\\d+-'), prefix + nextIndex + '-'));
}
if (el.name && el.name.indexOf('-id') !== -1) {
el.value = '';
} else if (el.type !== 'hidden') {
el.value = '';
}
});
var amountCell = clone.querySelector('.row-amount');
if (amountCell) amountCell.textContent = '—';
tbody.appendChild(clone);
reindexRows();
});
})();
</script>
{% endblock %}