412 lines
11 KiB
HTML
412 lines
11 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block content %}
|
||
<div class="page-header">
|
||
<h2>Редактирование заказа #{{ order.id }}</h2>
|
||
<a href="{{ url_for('index') }}" class="btn-back">Назад к списку</a>
|
||
</div>
|
||
|
||
<form method="POST" class="order-form" id="editOrderForm">
|
||
<div class="form-section">
|
||
<h3>Информация о заказе</h3>
|
||
|
||
<div class="form-group">
|
||
<label for="order_date">Дата заказа *</label>
|
||
<input type="date" name="order_date" id="order_date" value="{{ order.order_date }}" required>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="notes">Примечания</label>
|
||
<textarea name="notes" id="notes" rows="3">{{ order.notes or '' }}</textarea>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="form-section">
|
||
<h3>Позиции заказа</h3>
|
||
<p class="info-text">Выберите товары для заказа</p>
|
||
|
||
<div id="items-container">
|
||
{% for item in items %}
|
||
<div class="item-row" id="item-row-{{ loop.index }}">
|
||
<div class="item-fields">
|
||
<div class="form-group">
|
||
<label>Товар</label>
|
||
<select name="product_id[]" class="product-select" onchange="updatePrice(this)">
|
||
<option value="">Выберите товар</option>
|
||
{% for product in products %}
|
||
<option value="{{ product.id }}"
|
||
data-price="{{ product.min_partner_price }}"
|
||
{% if product.id == item.product_id %}selected{% endif %}>
|
||
{{ product.product_name }} ({{ product.type_name }})
|
||
</option>
|
||
{% endfor %}
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>Количество</label>
|
||
<input type="number" name="quantity[]" class="quantity-input"
|
||
min="1" value="{{ item.quantity }}" oninput="updateItemTotal(this)">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>Цена</label>
|
||
<input type="number" name="price[]" class="price-input"
|
||
step="0.01" min="0.01" value="{{ item.price_at_order }}" readonly>
|
||
</div>
|
||
|
||
<div class="item-total">
|
||
<label>Сумма с наценкой:</label>
|
||
<span class="item-total-value">{{ "%.2f"|format(item.quantity * item.price_at_order * 1.1) }} ₽</span>
|
||
</div>
|
||
|
||
<button type="button" class="btn-remove-item" onclick="removeItem({{ loop.index }})"
|
||
{% if items|length == 1 %}style="display: none;"{% endif %}>×</button>
|
||
</div>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
|
||
<button type="button" class="btn-add-item" onclick="addItem()">+ Добавить позицию</button>
|
||
</div>
|
||
|
||
<div class="form-actions">
|
||
<button type="submit" class="btn-submit">Сохранить изменения</button>
|
||
<a href="{{ url_for('index') }}" class="btn-back">Отмена</a>
|
||
</div>
|
||
</form>
|
||
|
||
<script>
|
||
let itemCount = {{ items|length }};
|
||
|
||
function addItem() {
|
||
itemCount++;
|
||
const container = document.getElementById('items-container');
|
||
const newRow = document.createElement('div');
|
||
newRow.className = 'item-row';
|
||
newRow.id = `item-row-${itemCount}`;
|
||
|
||
let options = '<option value="">Выберите товар</option>';
|
||
{% for product in products %}
|
||
options += `<option value="{{ product.id }}" data-price="{{ product.min_partner_price }}">
|
||
{{ product.product_name }} ({{ product.type_name }})
|
||
</option>`;
|
||
{% endfor %}
|
||
|
||
newRow.innerHTML = `
|
||
<div class="item-fields">
|
||
<div class="form-group">
|
||
<label>Товар</label>
|
||
<select name="product_id[]" class="product-select" onchange="updatePrice(this)">
|
||
${options}
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>Количество</label>
|
||
<input type="number" name="quantity[]" class="quantity-input"
|
||
min="1" value="1" oninput="updateItemTotal(this)">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>Цена</label>
|
||
<input type="number" name="price[]" class="price-input"
|
||
step="0.01" min="0.01" readonly>
|
||
</div>
|
||
|
||
<div class="item-total">
|
||
<label>Сумма с наценкой:</label>
|
||
<span class="item-total-value">0.00 ₽</span>
|
||
</div>
|
||
|
||
<button type="button" class="btn-remove-item" onclick="removeItem(${itemCount})">×</button>
|
||
</div>
|
||
`;
|
||
|
||
container.appendChild(newRow);
|
||
updateRemoveButtons();
|
||
}
|
||
|
||
function removeItem(id) {
|
||
const row = document.getElementById(`item-row-${id}`);
|
||
if (row) {
|
||
row.remove();
|
||
updateRemoveButtons();
|
||
}
|
||
}
|
||
|
||
function updateRemoveButtons() {
|
||
const rows = document.querySelectorAll('.item-row');
|
||
rows.forEach((row, index) => {
|
||
const btn = row.querySelector('.btn-remove-item');
|
||
if (btn) {
|
||
btn.style.display = rows.length > 1 ? 'block' : 'none';
|
||
}
|
||
});
|
||
}
|
||
|
||
function updatePrice(select) {
|
||
const row = select.closest('.item-row');
|
||
const priceInput = row.querySelector('.price-input');
|
||
const selectedOption = select.options[select.selectedIndex];
|
||
|
||
if (selectedOption && selectedOption.dataset.price) {
|
||
priceInput.value = selectedOption.dataset.price;
|
||
} else {
|
||
priceInput.value = '';
|
||
}
|
||
|
||
updateItemTotal(priceInput);
|
||
}
|
||
|
||
function updateItemTotal(input) {
|
||
const row = input.closest('.item-row');
|
||
const quantity = parseFloat(row.querySelector('.quantity-input').value) || 0;
|
||
const price = parseFloat(row.querySelector('.price-input').value) || 0;
|
||
const totalSpan = row.querySelector('.item-total-value');
|
||
|
||
const totalWithMarkup = quantity * price * 1.1;
|
||
totalSpan.textContent = totalWithMarkup.toFixed(2) + ' ₽';
|
||
}
|
||
|
||
document.getElementById('editOrderForm').addEventListener('submit', function(e) {
|
||
const rows = document.querySelectorAll('.item-row');
|
||
let hasValidItems = false;
|
||
|
||
rows.forEach((row, index) => {
|
||
const select = row.querySelector('.product-select');
|
||
const quantity = row.querySelector('.quantity-input');
|
||
const price = row.querySelector('.price-input');
|
||
|
||
if (select.value && quantity.value && price.value) {
|
||
hasValidItems = true;
|
||
}
|
||
});
|
||
|
||
if (!hasValidItems) {
|
||
e.preventDefault();
|
||
alert('Добавьте хотя бы одну позицию с корректными данными');
|
||
}
|
||
});
|
||
|
||
// Инициализация обработчиков
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
document.querySelectorAll('.product-select').forEach(select => {
|
||
select.addEventListener('change', function() {
|
||
updatePrice(this);
|
||
});
|
||
});
|
||
|
||
document.querySelectorAll('.quantity-input').forEach(input => {
|
||
input.addEventListener('input', function() {
|
||
updateItemTotal(this);
|
||
});
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<style>
|
||
.order-form {
|
||
background: white;
|
||
border-radius: 8px;
|
||
padding: 25px;
|
||
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||
max-width: 1000px;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.form-section {
|
||
margin-bottom: 30px;
|
||
padding-bottom: 20px;
|
||
border-bottom: 2px solid #E0E0E0;
|
||
}
|
||
|
||
.form-section h3 {
|
||
color: #696969;
|
||
margin-bottom: 20px;
|
||
font-size: 1.3rem;
|
||
}
|
||
|
||
.form-group {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.form-group label {
|
||
display: block;
|
||
margin-bottom: 5px;
|
||
font-weight: 600;
|
||
color: #555;
|
||
}
|
||
|
||
.form-group input,
|
||
.form-group select,
|
||
.form-group textarea {
|
||
width: 100%;
|
||
padding: 10px;
|
||
border: 1px solid #E0E0E0;
|
||
border-radius: 4px;
|
||
font-family: 'Calibri', sans-serif;
|
||
font-size: 1rem;
|
||
transition: border-color 0.3s;
|
||
}
|
||
|
||
.form-group input:focus,
|
||
.form-group select:focus,
|
||
.form-group textarea:focus {
|
||
outline: none;
|
||
border-color: #696969;
|
||
}
|
||
|
||
.stock-hint {
|
||
display: block;
|
||
margin-top: 5px;
|
||
color: #696969;
|
||
font-size: 0.9rem;
|
||
}
|
||
|
||
.stock-hint .max-stock {
|
||
font-weight: 600;
|
||
color: #4CAF50;
|
||
}
|
||
|
||
.item-row {
|
||
background-color: #F5F5F5;
|
||
border-radius: 8px;
|
||
padding: 15px;
|
||
margin-bottom: 15px;
|
||
border-left: 4px solid #696969;
|
||
}
|
||
|
||
.item-fields {
|
||
display: grid;
|
||
grid-template-columns: 2fr 1fr 1fr 1fr auto;
|
||
gap: 15px;
|
||
align-items: start;
|
||
}
|
||
|
||
.item-total {
|
||
padding-top: 25px;
|
||
font-weight: 600;
|
||
color: #696969;
|
||
}
|
||
|
||
.item-total label {
|
||
display: block;
|
||
font-size: 0.9rem;
|
||
color: #666;
|
||
margin-bottom: 5px;
|
||
}
|
||
|
||
.btn-add-item {
|
||
background-color: #696969;
|
||
color: white;
|
||
border: none;
|
||
padding: 12px 20px;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 1rem;
|
||
font-weight: 600;
|
||
width: 100%;
|
||
margin-top: 10px;
|
||
transition: background-color 0.3s;
|
||
}
|
||
|
||
.btn-add-item:hover {
|
||
background-color: #555;
|
||
}
|
||
|
||
.btn-remove-item {
|
||
background-color: #ff6b6b;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
width: 36px;
|
||
height: 36px;
|
||
cursor: pointer;
|
||
font-size: 1.2rem;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
transition: background-color 0.3s;
|
||
margin-top: 25px;
|
||
}
|
||
|
||
.btn-remove-item:hover {
|
||
background-color: #ff5252;
|
||
}
|
||
|
||
.form-actions {
|
||
text-align: center;
|
||
margin-top: 30px;
|
||
display: flex;
|
||
justify-content: center;
|
||
gap: 10px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.btn-submit {
|
||
background-color: #696969;
|
||
color: white;
|
||
border: none;
|
||
padding: 12px 30px;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 1.1rem;
|
||
font-weight: 600;
|
||
transition: background-color 0.3s;
|
||
}
|
||
|
||
.btn-submit:hover {
|
||
background-color: #555;
|
||
}
|
||
|
||
.btn-delete {
|
||
background-color: #dc3545;
|
||
color: white;
|
||
border: none;
|
||
padding: 12px 30px;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 1.1rem;
|
||
font-weight: 600;
|
||
transition: background-color 0.3s;
|
||
}
|
||
|
||
.btn-delete:hover {
|
||
background-color: #c82333;
|
||
}
|
||
|
||
.btn-back {
|
||
display: inline-block;
|
||
background-color: #E0E0E0;
|
||
color: #696969;
|
||
text-decoration: none;
|
||
padding: 12px 30px;
|
||
border-radius: 4px;
|
||
font-weight: 600;
|
||
transition: background-color 0.3s;
|
||
}
|
||
|
||
.btn-back:hover {
|
||
background-color: #D0D0D0;
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.item-fields {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.btn-remove-item {
|
||
width: 100%;
|
||
}
|
||
|
||
.form-actions {
|
||
flex-direction: column;
|
||
}
|
||
|
||
.btn-submit, .btn-delete, .btn-back {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
{% endblock %} |